Merge 'Namespace functions that operate on Value' from Pedro Muniz

This PR is extracted from #1674. This PR creates the optional feature
flag `simulator` that exposes the numeric module and enables an optional
Serde derive on limbo's `Value` type. Additionally, it also namespaces
all of the exec_* functions that operate on a `Value` or indirectly
operate on a `Value` (e.g `exec_like` operates on a pattern string that
is derived from the `Value`). This is necessary so that instead of
reimplementing all of the expected behaviours of different operations
inside the simulator, we can just tap into the existing code we already
have. The next step for this will be wrap be to use `Value` inside the
simulator, which is something that I did in #1674.

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #1692
This commit is contained in:
Pere Diaz Bou
2025-06-10 10:54:38 +02:00
8 changed files with 1216 additions and 1154 deletions

2
Cargo.lock generated
View File

@@ -1841,6 +1841,7 @@ dependencies = [
"rusqlite",
"rustix 1.0.7",
"ryu",
"serde",
"sorted-vec",
"strum",
"strum_macros",
@@ -2000,6 +2001,7 @@ dependencies = [
"phf",
"phf_codegen",
"phf_shared",
"serde",
"strum",
"strum_macros",
"uncased",

View File

@@ -54,6 +54,8 @@ limbo_time = { path = "extensions/time", version = "0.0.22-pre.1" }
limbo_uuid = { path = "extensions/uuid", version = "0.0.22-pre.1" }
strum = { version = "0.26", features = ["derive"] }
strum_macros = "0.26"
serde = "1.0"
serde_json = "1.0"
[profile.release]
debug = "line-tables-only"

View File

@@ -44,7 +44,7 @@ tracing-appender = "0.2.3"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
toml = {version = "0.8.20", features = ["preserve_order"]}
schemars = {version = "0.8.22", features = ["preserve_order"]}
serde = {version = "1.0.218", features = ["derive"]}
serde = { workspace = true, features = ["derive"]}
validator = {version = "0.20.0", features = ["derive"]}
toml_edit = {version = "0.22.24", features = ["serde"]}

View File

@@ -31,6 +31,8 @@ static = ["limbo_ext/static"]
fuzz = []
csv = ["limbo_csv/static"]
omit_autovacuum = []
simulator = ["fuzz", "serde"]
serde = ["dep:serde"]
[target.'cfg(target_os = "linux")'.dependencies]
io-uring = { version = "0.7.5", optional = true }
@@ -80,6 +82,7 @@ ryu = "1.0.19"
uncased = "0.9.10"
strum_macros = { workspace = true }
bitflags = "2.9.0"
serde = { workspace = true , optional = true, features = ["derive"] }
[build-dependencies]
chrono = { version = "0.4.38", default-features = false }

View File

@@ -1,5 +1,7 @@
use limbo_ext::{AggCtx, FinalizeFunction, StepFunction};
use limbo_sqlite3_parser::ast::SortOrder;
#[cfg(feature = "serde")]
use serde::Deserialize;
use crate::error::LimboError;
use crate::ext::{ExtValue, ExtValueType};
@@ -42,6 +44,7 @@ impl Display for ValueType {
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum TextSubtype {
Text,
#[cfg(feature = "json")]
@@ -49,6 +52,7 @@ pub enum TextSubtype {
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Text {
pub value: Vec<u8>,
pub subtype: TextSubtype,
@@ -108,10 +112,36 @@ impl TextRef {
}
}
#[cfg(feature = "serde")]
fn float_to_string<S>(float: &f64, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&format!("{}", float))
}
#[cfg(feature = "serde")]
fn string_to_float<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
s.parse().map_err(serde::de::Error::custom)
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Value {
Null,
Integer(i64),
// we use custom serialization to preserve float precision
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "float_to_string",
deserialize_with = "string_to_float"
)
)]
Float(f64),
Text(Text),
Blob(Vec<u8>),

File diff suppressed because it is too large Load Diff

View File

@@ -26,8 +26,8 @@ regex-syntax = { version = "0.8.5", default-features = false, features = [
] }
anarchist-readable-name-generator-lib = "=0.1.2"
clap = { version = "4.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
notify = "8.0.0"
rusqlite = { version = "0.34", features = ["bundled"] }
dirs = "6.0.0"

View File

@@ -34,6 +34,7 @@ indexmap = "2.0"
miette = "7.4.0"
strum = { workspace = true }
strum_macros = {workspace = true }
serde = { workspace = true , optional = true, features = ["derive"] }
[dev-dependencies]
env_logger = { version = "0.11", default-features = false }