accept base64-encoded vecs

main
Ziyang Hu 1 year ago
parent 01403bd65a
commit 919510b0f4

@ -8,6 +8,7 @@
use std::cmp::Reverse; use std::cmp::Reverse;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::mem;
use std::ops::{Div, Rem}; use std::ops::{Div, Rem};
use std::str::FromStr; use std::str::FromStr;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
@ -740,10 +741,10 @@ pub(crate) fn op_exp(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.exp())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.exp()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.exp())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.exp()))));
} }
_ => bail!("'exp' requires numbers"), _ => bail!("'exp' requires numbers"),
}; };
@ -756,10 +757,10 @@ pub(crate) fn op_exp2(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.exp2())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.exp2()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.exp2())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.exp2()))));
} }
_ => bail!("'exp2' requires numbers"), _ => bail!("'exp2' requires numbers"),
}; };
@ -772,10 +773,10 @@ pub(crate) fn op_ln(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.ln())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.ln()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.ln())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.ln()))));
} }
_ => bail!("'ln' requires numbers"), _ => bail!("'ln' requires numbers"),
}; };
@ -788,10 +789,10 @@ pub(crate) fn op_log2(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.log2())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.log2()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.log2())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.log2()))));
} }
_ => bail!("'log2' requires numbers"), _ => bail!("'log2' requires numbers"),
}; };
@ -804,10 +805,10 @@ pub(crate) fn op_log10(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.log10())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.log10()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.log10())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.log10()))));
} }
_ => bail!("'log10' requires numbers"), _ => bail!("'log10' requires numbers"),
}; };
@ -820,10 +821,10 @@ pub(crate) fn op_sin(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.sin())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.sin()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.sin())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.sin()))));
} }
_ => bail!("'sin' requires numbers"), _ => bail!("'sin' requires numbers"),
}; };
@ -836,10 +837,10 @@ pub(crate) fn op_cos(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.cos())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.cos()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.cos())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.cos()))));
} }
_ => bail!("'cos' requires numbers"), _ => bail!("'cos' requires numbers"),
}; };
@ -852,10 +853,10 @@ pub(crate) fn op_tan(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.tan())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.tan()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.tan())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.tan()))));
} }
_ => bail!("'tan' requires numbers"), _ => bail!("'tan' requires numbers"),
}; };
@ -868,10 +869,10 @@ pub(crate) fn op_asin(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.asin())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.asin()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.asin())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.asin()))));
} }
_ => bail!("'asin' requires numbers"), _ => bail!("'asin' requires numbers"),
}; };
@ -884,10 +885,10 @@ pub(crate) fn op_acos(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.acos())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.acos()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.acos())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.acos()))));
} }
_ => bail!("'acos' requires numbers"), _ => bail!("'acos' requires numbers"),
}; };
@ -900,10 +901,10 @@ pub(crate) fn op_atan(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.atan())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.atan()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.atan())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.atan()))));
} }
_ => bail!("'atan' requires numbers"), _ => bail!("'atan' requires numbers"),
}; };
@ -932,10 +933,10 @@ pub(crate) fn op_sinh(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.sinh())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.sinh()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.sinh())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.sinh()))));
} }
_ => bail!("'sinh' requires numbers"), _ => bail!("'sinh' requires numbers"),
}; };
@ -948,10 +949,10 @@ pub(crate) fn op_cosh(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.cosh())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.cosh()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.cosh())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.cosh()))));
} }
_ => bail!("'cosh' requires numbers"), _ => bail!("'cosh' requires numbers"),
}; };
@ -964,10 +965,10 @@ pub(crate) fn op_tanh(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.tanh())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.tanh()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.tanh())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.tanh()))));
} }
_ => bail!("'tanh' requires numbers"), _ => bail!("'tanh' requires numbers"),
}; };
@ -980,10 +981,10 @@ pub(crate) fn op_asinh(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.asinh())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.asinh()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.asinh())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.asinh()))));
} }
_ => bail!("'asinh' requires numbers"), _ => bail!("'asinh' requires numbers"),
}; };
@ -996,10 +997,10 @@ pub(crate) fn op_acosh(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.acosh())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.acosh()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.acosh())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.acosh()))));
} }
_ => bail!("'acosh' requires numbers"), _ => bail!("'acosh' requires numbers"),
}; };
@ -1012,10 +1013,10 @@ pub(crate) fn op_atanh(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.atanh())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.atanh()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.atanh())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.atanh()))));
} }
_ => bail!("'atanh' requires numbers"), _ => bail!("'atanh' requires numbers"),
}; };
@ -1028,10 +1029,10 @@ pub(crate) fn op_sqrt(args: &[DataValue]) -> Result<DataValue> {
DataValue::Num(Num::Int(i)) => *i as f64, DataValue::Num(Num::Int(i)) => *i as f64,
DataValue::Num(Num::Float(f)) => *f, DataValue::Num(Num::Float(f)) => *f,
DataValue::Vec(Vector::F32(v)) => { DataValue::Vec(Vector::F32(v)) => {
return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.sqrt())))) return Ok(DataValue::Vec(Vector::F32(v.mapv(|x| x.sqrt()))));
} }
DataValue::Vec(Vector::F64(v)) => { DataValue::Vec(Vector::F64(v)) => {
return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.sqrt())))) return Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x.sqrt()))));
} }
_ => bail!("'sqrt' requires numbers"), _ => bail!("'sqrt' requires numbers"),
}; };
@ -1622,9 +1623,9 @@ pub(crate) fn op_haversine(args: &[DataValue]) -> Result<DataValue> {
let lon2 = args[3].get_float().ok_or_else(miette)?; let lon2 = args[3].get_float().ok_or_else(miette)?;
let ret = 2. let ret = 2.
* f64::asin(f64::sqrt( * f64::asin(f64::sqrt(
f64::sin((lat1 - lat2) / 2.).powi(2) f64::sin((lat1 - lat2) / 2.).powi(2)
+ f64::cos(lat1) * f64::cos(lat2) * f64::sin((lon1 - lon2) / 2.).powi(2), + f64::cos(lat1) * f64::cos(lat2) * f64::sin((lon1 - lon2) / 2.).powi(2),
)); ));
Ok(DataValue::from(ret)) Ok(DataValue::from(ret))
} }
@ -1637,9 +1638,9 @@ pub(crate) fn op_haversine_deg_input(args: &[DataValue]) -> Result<DataValue> {
let lon2 = args[3].get_float().ok_or_else(miette)? * f64::PI() / 180.; let lon2 = args[3].get_float().ok_or_else(miette)? * f64::PI() / 180.;
let ret = 2. let ret = 2.
* f64::asin(f64::sqrt( * f64::asin(f64::sqrt(
f64::sin((lat1 - lat2) / 2.).powi(2) f64::sin((lat1 - lat2) / 2.).powi(2)
+ f64::cos(lat1) * f64::cos(lat2) * f64::sin((lon1 - lon2) / 2.).powi(2), + f64::cos(lat1) * f64::cos(lat2) * f64::sin((lon1 - lon2) / 2.).powi(2),
)); ));
Ok(DataValue::from(ret)) Ok(DataValue::from(ret))
} }
@ -1970,7 +1971,7 @@ pub(crate) fn op_to_int(args: &[DataValue]) -> Result<DataValue> {
.map_err(|_| miette!("The string cannot be interpreted as int"))? .map_err(|_| miette!("The string cannot be interpreted as int"))?
.into() .into()
} }
DataValue::Validity(vld) => DataValue::Num(Num::Int(vld.timestamp.0 .0)), DataValue::Validity(vld) => DataValue::Num(Num::Int(vld.timestamp.0.0)),
v => bail!("'to_int' does not recognize {:?}", v), v => bail!("'to_int' does not recognize {:?}", v),
}) })
} }
@ -2084,6 +2085,21 @@ pub(crate) fn op_vec(args: &[DataValue]) -> Result<DataValue> {
Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x as f64)))) Ok(DataValue::Vec(Vector::F64(v.mapv(|x| x as f64))))
} }
}, },
DataValue::Str(s) => {
let bytes = STANDARD.decode(s).map_err(|_| miette!("Data is not base64 encoded"))?;
match t {
VecElementType::F32 => {
let f32_count = bytes.len() / mem::size_of::<f32>();
let arr = unsafe { ndarray::ArrayView1::from_shape_ptr(ndarray::Dim([f32_count]), bytes.as_ptr() as *const f32) };
Ok(DataValue::Vec(Vector::F32(arr.to_owned())))
}
VecElementType::F64 => {
let f64_count = bytes.len() / mem::size_of::<f64>();
let arr = unsafe { ndarray::ArrayView1::from_shape_ptr(ndarray::Dim([f64_count]), bytes.as_ptr() as *const f64) };
Ok(DataValue::Vec(Vector::F64(arr.to_owned())))
}
}
}
_ => bail!("'vec' requires a list or a vector"), _ => bail!("'vec' requires a list or a vector"),
} }
} }
@ -2412,12 +2428,12 @@ pub(crate) fn op_now(_args: &[DataValue]) -> Result<DataValue> {
pub(crate) fn current_validity() -> ValidityTs { pub(crate) fn current_validity() -> ValidityTs {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let ts_micros = { let ts_micros = {
let now = SystemTime::now(); let now = SystemTime::now();
now.duration_since(UNIX_EPOCH).unwrap().as_micros() as i64 now.duration_since(UNIX_EPOCH).unwrap().as_micros() as i64
}; };
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
let ts_micros = { (Date::now() * 1000.) as i64 }; let ts_micros = { (Date::now() * 1000.) as i64 };
ValidityTs(Reverse(ts_micros)) ValidityTs(Reverse(ts_micros))
} }
@ -2432,7 +2448,7 @@ define_op!(OP_FORMAT_TIMESTAMP, 1, true);
pub(crate) fn op_format_timestamp(args: &[DataValue]) -> Result<DataValue> { pub(crate) fn op_format_timestamp(args: &[DataValue]) -> Result<DataValue> {
let dt = { let dt = {
let millis = match &args[0] { let millis = match &args[0] {
DataValue::Validity(vld) => vld.timestamp.0 .0 / 1000, DataValue::Validity(vld) => vld.timestamp.0.0 / 1000,
v => { v => {
let f = v let f = v
.get_float() .get_float()
@ -2486,14 +2502,14 @@ pub(crate) fn op_rand_uuid_v1(_args: &[DataValue]) -> Result<DataValue> {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let uuid_ctx = uuid::v1::Context::new(rng.gen()); let uuid_ctx = uuid::v1::Context::new(rng.gen());
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
let ts = { let ts = {
let since_epoch: f64 = Date::now(); let since_epoch: f64 = Date::now();
let seconds = since_epoch.floor(); let seconds = since_epoch.floor();
let fractional = (since_epoch - seconds) * 1.0e9; let fractional = (since_epoch - seconds) * 1.0e9;
Timestamp::from_unix(uuid_ctx, seconds as u64, fractional as u32) Timestamp::from_unix(uuid_ctx, seconds as u64, fractional as u32)
}; };
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let ts = { let ts = {
let now = SystemTime::now(); let now = SystemTime::now();
let since_epoch = now.duration_since(UNIX_EPOCH).unwrap(); let since_epoch = now.duration_since(UNIX_EPOCH).unwrap();
Timestamp::from_unix(uuid_ctx, since_epoch.as_secs(), since_epoch.subsec_nanos()) Timestamp::from_unix(uuid_ctx, since_epoch.as_secs(), since_epoch.subsec_nanos())

@ -94,7 +94,7 @@ impl Display for QueryOutOptions {
)) = &self.store_relation )) = &self.store_relation
{ {
if *return_mutation == ReturnMutation::Returning { if *return_mutation == ReturnMutation::Returning {
write!(f, ":returning\n")?; writeln!(f, ":returning")?;
} }
match op { match op {
RelationOp::Create => { RelationOp::Create => {

@ -71,8 +71,7 @@ pub(crate) fn kahn_g(graph: &DirectedCsrGraph<u32>, poison: Poison) -> Result<Ve
} }
} }
while !pending.is_empty() { while let Some(removed) = pending.pop() {
let removed = pending.pop().unwrap();
sorted.push(removed); sorted.push(removed);
for nxt in graph.out_neighbors(removed) { for nxt in graph.out_neighbors(removed) {
in_degree[*nxt as usize] -= 1; in_degree[*nxt as usize] -= 1;

@ -191,7 +191,7 @@ impl DbInstance {
} }
/// `run_script` with mutable script and no parameters /// `run_script` with mutable script and no parameters
pub fn run_default(&self, payload: &str) -> Result<NamedRows> { pub fn run_default(&self, payload: &str) -> Result<NamedRows> {
return self.run_script(payload, BTreeMap::new(), ScriptMutability::Mutable); self.run_script(payload, BTreeMap::new(), ScriptMutability::Mutable)
} }
/// Run the CozoScript passed in. The `params` argument is a map of parameters. /// Run the CozoScript passed in. The `params` argument is a map of parameters.
/// Fold any error into the return JSON itself. /// Fold any error into the return JSON itself.
@ -203,13 +203,13 @@ impl DbInstance {
mutability: ScriptMutability, mutability: ScriptMutability,
) -> JsonValue { ) -> JsonValue {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let start = Instant::now(); let start = Instant::now();
match self.run_script(payload, params, mutability) { match self.run_script(payload, params, mutability) {
Ok(named_rows) => { Ok(named_rows) => {
let mut j_val = named_rows.into_json(); let mut j_val = named_rows.into_json();
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let took = start.elapsed().as_secs_f64(); let took = start.elapsed().as_secs_f64();
let map = j_val.as_object_mut().unwrap(); let map = j_val.as_object_mut().unwrap();
map.insert("ok".to_string(), json!(true)); map.insert("ok".to_string(), json!(true));
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -233,7 +233,7 @@ impl DbInstance {
.collect(), .collect(),
Err(_) => { Err(_) => {
return json!({"ok": false, "message": "params argument is not a JSON map"}) return json!({"ok": false, "message": "params argument is not a JSON map"})
.to_string() .to_string();
} }
} }
}; };
@ -246,13 +246,13 @@ impl DbInstance {
ScriptMutability::Mutable ScriptMutability::Mutable
}, },
) )
.to_string() .to_string()
} }
/// Dispatcher method. See [crate::Db::export_relations]. /// Dispatcher method. See [crate::Db::export_relations].
pub fn export_relations<I, T>(&self, relations: I) -> Result<BTreeMap<String, NamedRows>> pub fn export_relations<I, T>(&self, relations: I) -> Result<BTreeMap<String, NamedRows>>
where where
T: AsRef<str>, T: AsRef<str>,
I: Iterator<Item = T>, I: Iterator<Item=T>,
{ {
match self { match self {
DbInstance::Mem(db) => db.export_relations(relations), DbInstance::Mem(db) => db.export_relations(relations),
@ -451,8 +451,8 @@ impl DbInstance {
} }
/// Dispatcher method. See [crate::Db::register_fixed_rule]. /// Dispatcher method. See [crate::Db::register_fixed_rule].
pub fn register_fixed_rule<R>(&self, name: String, rule_impl: R) -> Result<()> pub fn register_fixed_rule<R>(&self, name: String, rule_impl: R) -> Result<()>
where where
R: FixedRule + 'static, R: FixedRule + 'static,
{ {
match self { match self {
DbInstance::Mem(db) => db.register_fixed_rule(name, rule_impl), DbInstance::Mem(db) => db.register_fixed_rule(name, rule_impl),

@ -269,7 +269,7 @@ pub(crate) fn parse_expressions(
.next() .next()
.unwrap(); .unwrap();
Ok(build_expr(parsed.into_inner().next().unwrap(), param_pool)?) build_expr(parsed.into_inner().next().unwrap(), param_pool)
} }
pub(crate) fn parse_script( pub(crate) fn parse_script(

@ -235,7 +235,7 @@ pub(crate) fn parse_query(
for s in datalist.next().unwrap().into_inner() { for s in datalist.next().unwrap().into_inner() {
if s.as_rule() == Rule::param { if s.as_rule() == Rule::param {
head.push(Symbol::new( head.push(Symbol::new(
s.as_str().strip_prefix("$").unwrap(), s.as_str().strip_prefix('$').unwrap(),
Default::default(), Default::default(),
)); ));
} }

@ -224,7 +224,7 @@ impl<'a> SessionTx<'a> {
span: SourceSpan, span: SourceSpan,
) -> Result<()> { ) -> Result<()> {
let is_callback_target = callback_targets.contains(&relation_store.name) let is_callback_target = callback_targets.contains(&relation_store.name)
|| force_collect == &relation_store.name; || force_collect == relation_store.name;
if relation_store.access_level < AccessLevel::Protected { if relation_store.access_level < AccessLevel::Protected {
bail!(InsufficientAccessLevel( bail!(InsufficientAccessLevel(
@ -468,7 +468,7 @@ impl<'a> SessionTx<'a> {
for (name, (_, manifest)) in relation_store.fts_indices.iter() { for (name, (_, manifest)) in relation_store.fts_indices.iter() {
let tokenizer = self let tokenizer = self
.tokenizers .tokenizers
.get(&name, &manifest.tokenizer, &manifest.filters)?; .get(name, &manifest.tokenizer, &manifest.filters)?;
let parsed = CozoScriptParser::parse(Rule::expr, &manifest.extractor) let parsed = CozoScriptParser::parse(Rule::expr, &manifest.extractor)
.into_diagnostic()? .into_diagnostic()?
@ -483,7 +483,7 @@ impl<'a> SessionTx<'a> {
for (name, (_, _, manifest)) in relation_store.lsh_indices.iter() { for (name, (_, _, manifest)) in relation_store.lsh_indices.iter() {
let tokenizer = self let tokenizer = self
.tokenizers .tokenizers
.get(&name, &manifest.tokenizer, &manifest.filters)?; .get(name, &manifest.tokenizer, &manifest.filters)?;
let parsed = CozoScriptParser::parse(Rule::expr, &manifest.extractor) let parsed = CozoScriptParser::parse(Rule::expr, &manifest.extractor)
.into_diagnostic()? .into_diagnostic()?
@ -534,7 +534,7 @@ impl<'a> SessionTx<'a> {
span: SourceSpan, span: SourceSpan,
) -> Result<()> { ) -> Result<()> {
let is_callback_target = callback_targets.contains(&relation_store.name) let is_callback_target = callback_targets.contains(&relation_store.name)
|| force_collect == &relation_store.name; || force_collect == relation_store.name;
if relation_store.access_level < AccessLevel::Protected { if relation_store.access_level < AccessLevel::Protected {
bail!(InsufficientAccessLevel( bail!(InsufficientAccessLevel(

@ -1173,9 +1173,9 @@ impl<'s, S: Storage<'s>> Db<S> {
) -> Result<NamedRows> { ) -> Result<NamedRows> {
match op { match op {
SysOp::Explain(prog) => { SysOp::Explain(prog) => {
let (normalized_program, _) = prog.clone().into_normalized_program(&tx)?; let (normalized_program, _) = prog.clone().into_normalized_program(tx)?;
let (stratified_program, _) = normalized_program.into_stratified_program()?; let (stratified_program, _) = normalized_program.into_stratified_program()?;
let program = stratified_program.magic_sets_rewrite(&tx)?; let program = stratified_program.magic_sets_rewrite(tx)?;
let compiled = tx.stratified_magic_compile(program)?; let compiled = tx.stratified_magic_compile(program)?;
self.explain_compiled(&compiled) self.explain_compiled(&compiled)
} }
@ -1213,7 +1213,7 @@ impl<'s, S: Storage<'s>> Db<S> {
let _guards = locks.iter().map(|l| l.read().unwrap()).collect_vec(); let _guards = locks.iter().map(|l| l.read().unwrap()).collect_vec();
let mut bounds = vec![]; let mut bounds = vec![];
for rs in rel_names { for rs in rel_names {
let bound = tx.destroy_relation(&rs)?; let bound = tx.destroy_relation(rs)?;
if !rs.is_temp_store_name() { if !rs.is_temp_store_name() {
bounds.extend(bound); bounds.extend(bound);
} }
@ -1227,7 +1227,7 @@ impl<'s, S: Storage<'s>> Db<S> {
)) ))
} }
SysOp::DescribeRelation(rel_name, description) => { SysOp::DescribeRelation(rel_name, description) => {
tx.describe_relation(&rel_name, description)?; tx.describe_relation(rel_name, description)?;
Ok(NamedRows::new( Ok(NamedRows::new(
vec![STATUS_STR.to_string()], vec![STATUS_STR.to_string()],
vec![vec![DataValue::from(OK_STR)]], vec![vec![DataValue::from(OK_STR)]],
@ -1238,14 +1238,14 @@ impl<'s, S: Storage<'s>> Db<S> {
bail!("Cannot create index in read-only mode"); bail!("Cannot create index in read-only mode");
} }
if skip_locking { if skip_locking {
tx.create_index(&rel_name, &idx_name, cols)?; tx.create_index(rel_name, idx_name, cols)?;
} else { } else {
let lock = self let lock = self
.obtain_relation_locks(iter::once(&rel_name.name)) .obtain_relation_locks(iter::once(&rel_name.name))
.pop() .pop()
.unwrap(); .unwrap();
let _guard = lock.write().unwrap(); let _guard = lock.write().unwrap();
tx.create_index(&rel_name, &idx_name, cols)?; tx.create_index(rel_name, idx_name, cols)?;
} }
Ok(NamedRows::new( Ok(NamedRows::new(
vec![STATUS_STR.to_string()], vec![STATUS_STR.to_string()],
@ -1315,14 +1315,14 @@ impl<'s, S: Storage<'s>> Db<S> {
bail!("Cannot remove index in read-only mode"); bail!("Cannot remove index in read-only mode");
} }
let bounds = if skip_locking { let bounds = if skip_locking {
tx.remove_index(&rel_name, &idx_name)? tx.remove_index(rel_name, idx_name)?
} else { } else {
let lock = self let lock = self
.obtain_relation_locks(iter::once(&rel_name.name)) .obtain_relation_locks(iter::once(&rel_name.name))
.pop() .pop()
.unwrap(); .unwrap();
let _guard = lock.read().unwrap(); let _guard = lock.read().unwrap();
tx.remove_index(&rel_name, &idx_name)? tx.remove_index(rel_name, idx_name)?
}; };
for (lower, upper) in bounds { for (lower, upper) in bounds {
@ -1333,8 +1333,8 @@ impl<'s, S: Storage<'s>> Db<S> {
vec![vec![DataValue::from(OK_STR)]], vec![vec![DataValue::from(OK_STR)]],
)) ))
} }
SysOp::ListColumns(rs) => self.list_columns(tx, &rs), SysOp::ListColumns(rs) => self.list_columns(tx, rs),
SysOp::ListIndices(rs) => self.list_indices(tx, &rs), SysOp::ListIndices(rs) => self.list_indices(tx, rs),
SysOp::RenameRelation(rename_pairs) => { SysOp::RenameRelation(rename_pairs) => {
if read_only { if read_only {
bail!("Cannot rename relations in read-only mode"); bail!("Cannot rename relations in read-only mode");
@ -1357,7 +1357,7 @@ impl<'s, S: Storage<'s>> Db<S> {
SysOp::ListRunning => self.list_running(), SysOp::ListRunning => self.list_running(),
SysOp::KillRunning(id) => { SysOp::KillRunning(id) => {
let queries = self.running_queries.lock().unwrap(); let queries = self.running_queries.lock().unwrap();
Ok(match queries.get(&id) { Ok(match queries.get(id) {
None => NamedRows::new( None => NamedRows::new(
vec![STATUS_STR.to_string()], vec![STATUS_STR.to_string()],
vec![vec![DataValue::from("NOT_FOUND")]], vec![vec![DataValue::from("NOT_FOUND")]],
@ -1372,7 +1372,7 @@ impl<'s, S: Storage<'s>> Db<S> {
}) })
} }
SysOp::ShowTrigger(name) => { SysOp::ShowTrigger(name) => {
let rel = tx.get_relation(&name, false)?; let rel = tx.get_relation(name, false)?;
let mut rows: Vec<Vec<JsonValue>> = vec![]; let mut rows: Vec<Vec<JsonValue>> = vec![];
for (i, trigger) in rel.put_triggers.iter().enumerate() { for (i, trigger) in rel.put_triggers.iter().enumerate() {
rows.push(vec![json!("put"), json!(i), json!(trigger)]) rows.push(vec![json!("put"), json!(i), json!(trigger)])

@ -560,7 +560,7 @@ impl<'a> SessionTx<'a> {
if name.name.starts_with('_') { if name.name.starts_with('_') {
bail!("Cannot set triggers for temp store") bail!("Cannot set triggers for temp store")
} }
let mut original = self.get_relation(&name, true)?; let mut original = self.get_relation(name, true)?;
if original.access_level < AccessLevel::Protected { if original.access_level < AccessLevel::Protected {
bail!(InsufficientAccessLevel( bail!(InsufficientAccessLevel(
original.name.to_string(), original.name.to_string(),
@ -723,7 +723,7 @@ impl<'a> SessionTx<'a> {
Ok(to_clean) Ok(to_clean)
} }
pub(crate) fn set_access_level(&mut self, rel: &Symbol, level: AccessLevel) -> Result<()> { pub(crate) fn set_access_level(&mut self, rel: &Symbol, level: AccessLevel) -> Result<()> {
let mut meta = self.get_relation(&rel, true)?; let mut meta = self.get_relation(rel, true)?;
meta.access_level = level; meta.access_level = level;
let name_key = vec![DataValue::Str(meta.name.clone())].encode_as_key(RelationId::SYSTEM); let name_key = vec![DataValue::Str(meta.name.clone())].encode_as_key(RelationId::SYSTEM);
@ -1422,7 +1422,7 @@ impl<'a> SessionTx<'a> {
let old_key = DataValue::Str(old.name.clone()); let old_key = DataValue::Str(old.name.clone());
let old_encoded = vec![old_key].encode_as_key(RelationId::SYSTEM); let old_encoded = vec![old_key].encode_as_key(RelationId::SYSTEM);
let mut rel = self.get_relation(&old, true)?; let mut rel = self.get_relation(old, true)?;
if rel.access_level < AccessLevel::Normal { if rel.access_level < AccessLevel::Normal {
bail!(InsufficientAccessLevel( bail!(InsufficientAccessLevel(
rel.name.to_string(), rel.name.to_string(),

Loading…
Cancel
Save