Apply new planner structure to virtual table impl

This commit is contained in:
PThorpe92
2025-02-01 18:51:27 -05:00
parent f5f77c0bd1
commit 661c74e338
9 changed files with 61 additions and 41 deletions

2
Cargo.lock generated
View File

@@ -1616,6 +1616,7 @@ dependencies = [
"limbo_macros",
"limbo_percentile",
"limbo_regexp",
"limbo_series",
"limbo_time",
"limbo_uuid",
"log",
@@ -1707,6 +1708,7 @@ version = "0.0.14"
dependencies = [
"limbo_ext",
"log",
"mimalloc",
]
[[package]]

View File

@@ -27,6 +27,7 @@ percentile = ["limbo_percentile/static"]
regexp = ["limbo_regexp/static"]
time = ["limbo_time/static"]
crypto = ["limbo_crypto/static"]
series = ["limbo_series/static"]
[target.'cfg(target_os = "linux")'.dependencies]
io-uring = { version = "0.6.1", optional = true }
@@ -67,6 +68,7 @@ limbo_regexp = { path = "../extensions/regexp", optional = true, features = ["st
limbo_percentile = { path = "../extensions/percentile", optional = true, features = ["static"] }
limbo_time = { path = "../extensions/time", optional = true, features = ["static"] }
limbo_crypto = { path = "../extensions/crypto", optional = true, features = ["static"] }
limbo_series = { path = "../extensions/series", optional = true, features = ["static"] }
miette = "7.4.0"
strum = "0.26"
parking_lot = "0.12.3"

View File

@@ -131,6 +131,7 @@ impl Database {
return ResultCode::Error;
};
let vtab_module = self.vtab_modules.get(name).unwrap().clone();
let vtab = VirtualTable {
name: name.to_string(),
implementation: vtab_module,
@@ -172,6 +173,10 @@ impl Database {
if unsafe { !limbo_crypto::register_extension_static(&ext_api).is_ok() } {
return Err("Failed to register crypto extension".to_string());
}
#[cfg(feature = "series")]
if unsafe { !limbo_series::register_extension_static(&ext_api).is_ok() } {
return Err("Failed to register series extension".to_string());
}
Ok(())
}
}

View File

@@ -1,7 +1,6 @@
use sqlite3_parser::ast::{self, CreateTableBody, Expr, FunctionTail, Literal};
use std::{rc::Rc, sync::Arc};
use sqlite3_parser::ast::{CreateTableBody, Expr, FunctionTail, Literal};
use crate::{
schema::{self, Column, Schema, Type},
Result, Statement, StepResult, IO,
@@ -308,7 +307,7 @@ pub fn exprs_are_equivalent(expr1: &Expr, expr2: &Expr) -> bool {
}
}
pub fn columns_from_create_table_body(body: CreateTableBody) -> Result<Vec<Column>, ()> {
pub fn columns_from_create_table_body(body: ast::CreateTableBody) -> Result<Vec<Column>, ()> {
let CreateTableBody::ColumnsAndConstraints { columns, .. } = body else {
return Err(());
};

View File

@@ -280,6 +280,7 @@ fn get_cursor_as_virtual_mut<'long, 'short>(
.as_virtual_mut();
cursor
}
struct Bitfield<const N: usize>([u64; N]);
impl<const N: usize> Bitfield<N> {

View File

@@ -99,8 +99,8 @@ pub type VtabFnEof = unsafe extern "C" fn(cursor: *mut c_void) -> bool;
pub trait VTabModule: 'static {
type VCursor: VTabCursor;
const NAME: &'static str;
fn name() -> &'static str;
fn connect(api: &ExtensionApi) -> ResultCode;
fn open() -> Self::VCursor;
fn filter(cursor: &mut Self::VCursor, arg_count: i32, args: &[Value]) -> ResultCode;

View File

@@ -6,10 +6,16 @@ edition.workspace = true
license.workspace = true
repository.workspace = true
[features]
static = ["limbo_ext/static"]
[lib]
crate-type = ["cdylib", "lib"]
[dependencies]
limbo_ext = { path = "../core"}
limbo_ext = { path = "../core", features = ["static"] }
log = "0.4.20"
[target.'cfg(not(target_family = "wasm"))'.dependencies]
mimalloc = { version = "*", default-features = false }

View File

@@ -1,21 +1,27 @@
use limbo_ext::{
register_extension, ExtensionApi, ResultCode, VTabCursor, VTabModule, VTabModuleDerive, Value,
ValueType,
};
register_extension! {
vtabs: { GenerateSeriesVTab }
}
macro_rules! try_option {
($expr:expr, $err:expr) => {
match $expr {
Some(val) => val,
None => return $err,
}
};
}
/// A virtual table that generates a sequence of integers
#[derive(Debug, VTabModuleDerive)]
struct GenerateSeriesVTab;
impl VTabModule for GenerateSeriesVTab {
type VCursor = GenerateSeriesCursor;
fn name() -> &'static str {
"generate_series"
}
const NAME: &'static str = "generate_series";
fn connect(api: &ExtensionApi) -> ResultCode {
// Create table schema
@@ -25,8 +31,7 @@ impl VTabModule for GenerateSeriesVTab {
stop INTEGER HIDDEN,
step INTEGER HIDDEN
)";
let name = Self::name();
api.declare_virtual_table(name, sql)
api.declare_virtual_table(Self::NAME, sql)
}
fn open() -> Self::VCursor {
@@ -43,35 +48,19 @@ impl VTabModule for GenerateSeriesVTab {
if arg_count == 0 || arg_count > 3 {
return ResultCode::InvalidArgs;
}
let start = {
if args[0].value_type() == ValueType::Integer {
args[0].to_integer().unwrap()
} else {
return ResultCode::InvalidArgs;
}
};
let stop = if args.len() == 1 {
i64::MAX
} else {
if args[1].value_type() == ValueType::Integer {
args[1].to_integer().unwrap()
} else {
return ResultCode::InvalidArgs;
}
};
let step = if args.len() <= 2 {
1
} else {
if args[2].value_type() == ValueType::Integer {
args[2].to_integer().unwrap()
} else {
return ResultCode::InvalidArgs;
}
};
let start = try_option!(args[0].to_integer(), ResultCode::InvalidArgs);
let stop = try_option!(
args.get(1).map(|v| v.to_integer().unwrap_or(i64::MAX)),
ResultCode::InvalidArgs
);
let step = try_option!(
args.get(2).map(|v| v.to_integer().unwrap_or(1)),
ResultCode::InvalidArgs
);
cursor.start = start;
cursor.current = start;
cursor.stop = stop;
cursor.step = step;
cursor.stop = stop;
ResultCode::OK
}

View File

@@ -343,6 +343,9 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
unsafe extern "C" fn #connect_fn_name(
db: *const ::std::ffi::c_void,
) -> ::limbo_ext::ResultCode {
if db.is_null() {
return ::limbo_ext::ResultCode::Error;
}
let api = unsafe { &*(db as *const ExtensionApi) };
<#struct_name as ::limbo_ext::VTabModule>::connect(api)
}
@@ -360,6 +363,9 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
argc: i32,
argv: *const ::limbo_ext::Value,
) -> ::limbo_ext::ResultCode {
if cursor.is_null() {
return ::limbo_ext::ResultCode::Error;
}
let cursor = unsafe { &mut *(cursor as *mut <#struct_name as ::limbo_ext::VTabModule>::VCursor) };
let args = std::slice::from_raw_parts(argv, argc as usize);
<#struct_name as ::limbo_ext::VTabModule>::filter(cursor, argc, args)
@@ -370,6 +376,9 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
cursor: *mut ::std::ffi::c_void,
idx: u32,
) -> ::limbo_ext::Value {
if cursor.is_null() {
return ::limbo_ext::Value::error(ResultCode::Error);
}
let cursor = unsafe { &mut *(cursor as *mut <#struct_name as ::limbo_ext::VTabModule>::VCursor) };
<#struct_name as ::limbo_ext::VTabModule>::column(cursor, idx)
}
@@ -378,6 +387,9 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
unsafe extern "C" fn #next_fn_name(
cursor: *mut ::std::ffi::c_void,
) -> ::limbo_ext::ResultCode {
if cursor.is_null() {
return ::limbo_ext::ResultCode::Error;
}
let cursor = unsafe { &mut *(cursor as *mut <#struct_name as ::limbo_ext::VTabModule>::VCursor) };
<#struct_name as ::limbo_ext::VTabModule>::next(cursor)
}
@@ -386,6 +398,9 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
unsafe extern "C" fn #eof_fn_name(
cursor: *mut ::std::ffi::c_void,
) -> bool {
if cursor.is_null() {
return true;
}
let cursor = unsafe { &mut *(cursor as *mut <#struct_name as ::limbo_ext::VTabModule>::VCursor) };
<#struct_name as ::limbo_ext::VTabModule>::eof(cursor)
}
@@ -399,7 +414,7 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
}
let api = &*api;
let name = <#struct_name as ::limbo_ext::VTabModule>::name();
let name = <#struct_name as ::limbo_ext::VTabModule>::NAME;
// name needs to be a c str FFI compatible, NOT CString
let name_c = std::ffi::CString::new(name).unwrap();
@@ -493,9 +508,9 @@ pub fn register_extension(input: TokenStream) -> TokenStream {
let result = unsafe{ #vtab_ident::#register_fn(api)};
if result == ::limbo_ext::ResultCode::OK {
let result = <#vtab_ident as ::limbo_ext::VTabModule>::connect(api);
return result;
} else {
return result;
if !result.is_ok() {
return result;
}
}
}
}
@@ -535,5 +550,6 @@ pub fn register_extension(input: TokenStream) -> TokenStream {
::limbo_ext::ResultCode::OK
}
};
TokenStream::from(expanded)
}