mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-17 14:04:34 +01:00
make column reuse blob/text fields
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use std::ffi::{c_char, c_void};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(C)]
|
||||
@@ -196,7 +195,7 @@ impl LimboValue {
|
||||
return limbo_core::OwnedValue::Null;
|
||||
}
|
||||
let bytes = self.value.to_bytes();
|
||||
limbo_core::OwnedValue::Blob(Rc::new(bytes.to_vec()))
|
||||
limbo_core::OwnedValue::Blob(bytes.to_vec())
|
||||
}
|
||||
ValueType::Null => limbo_core::OwnedValue::Null,
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ use jni::sys::{jdouble, jint, jlong};
|
||||
use jni::JNIEnv;
|
||||
use limbo_core::{OwnedValue, Statement, StepResult};
|
||||
use std::num::NonZero;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub const STEP_RESULT_ID_ROW: i32 = 10;
|
||||
#[allow(dead_code)]
|
||||
@@ -264,7 +263,7 @@ pub extern "system" fn Java_tech_turso_core_LimboStatement_bindBlob<'local>(
|
||||
|
||||
stmt.stmt.bind_at(
|
||||
NonZero::new(position as usize).unwrap(),
|
||||
OwnedValue::Blob(Rc::new(blob)),
|
||||
OwnedValue::Blob(blob),
|
||||
);
|
||||
SQLITE_OK
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ fn py_to_owned_value(obj: &Bound<PyAny>) -> Result<limbo_core::OwnedValue> {
|
||||
} else if let Ok(string) = obj.extract::<String>() {
|
||||
return Ok(OwnedValue::Text(Text::from_str(string)));
|
||||
} else if let Ok(bytes) = obj.downcast::<PyBytes>() {
|
||||
return Ok(OwnedValue::Blob(Rc::new(bytes.as_bytes().to_vec())));
|
||||
return Ok(OwnedValue::Blob(bytes.as_bytes().to_vec()));
|
||||
} else {
|
||||
return Err(PyErr::new::<ProgrammingError, _>(format!(
|
||||
"Unsupported Python type: {}",
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
opcodes_dictionary::OPCODE_DESCRIPTIONS,
|
||||
};
|
||||
use comfy_table::{Attribute, Cell, CellAlignment, Color, ContentArrangement, Row, Table};
|
||||
use limbo_core::{Database, LimboError, OwnedValue, RefValue, Statement, StepResult};
|
||||
use limbo_core::{Database, LimboError, RefValue, Statement, StepResult};
|
||||
|
||||
use clap::{Parser, ValueEnum};
|
||||
use rustyline::{history::DefaultHistory, Editor};
|
||||
|
||||
@@ -185,7 +185,7 @@ pub fn jsonb_remove(args: &[Register], json_cache: &JsonCacheCell) -> crate::Res
|
||||
}
|
||||
}
|
||||
|
||||
Ok(OwnedValue::Blob(Rc::new(json.data())))
|
||||
Ok(OwnedValue::Blob(json.data()))
|
||||
}
|
||||
|
||||
pub fn json_replace(args: &[Register], json_cache: &JsonCacheCell) -> crate::Result<OwnedValue> {
|
||||
@@ -554,7 +554,7 @@ mod tests {
|
||||
#[test]
|
||||
#[should_panic(expected = "blob is not supported!")]
|
||||
fn test_blob_not_supported() {
|
||||
let target = OwnedValue::Blob(Rc::new(vec![1, 2, 3]));
|
||||
let target = OwnedValue::Blob(vec![1, 2, 3]);
|
||||
let patch = create_text("{}");
|
||||
json_patch(&target, &patch).unwrap();
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ pub fn get_json(json_value: &OwnedValue, indent: Option<&str>) -> crate::Result<
|
||||
let jsonbin = Jsonb::new(b.len(), Some(b));
|
||||
jsonbin.is_valid()?;
|
||||
Ok(OwnedValue::Text(Text {
|
||||
value: Rc::new(jsonbin.to_string()?.into_bytes()),
|
||||
value: jsonbin.to_string()?.into_bytes(),
|
||||
subtype: TextSubtype::Json,
|
||||
}))
|
||||
}
|
||||
@@ -95,7 +95,7 @@ pub fn jsonb(json_value: &OwnedValue, cache: &JsonCacheCell) -> crate::Result<Ow
|
||||
|
||||
let jsonbin = cache.get_or_insert_with(json_value, json_conv_fn);
|
||||
match jsonbin {
|
||||
Ok(jsonbin) => Ok(OwnedValue::Blob(Rc::new(jsonbin.data()))),
|
||||
Ok(jsonbin) => Ok(OwnedValue::Blob(jsonbin.data())),
|
||||
Err(_) => {
|
||||
bail_parse_error!("malformed JSON")
|
||||
}
|
||||
@@ -405,7 +405,7 @@ fn json_string_to_db_type(
|
||||
) -> crate::Result<OwnedValue> {
|
||||
let mut json_string = json.to_string()?;
|
||||
if matches!(flag, OutputVariant::Binary) {
|
||||
return Ok(OwnedValue::Blob(Rc::new(json.data())));
|
||||
return Ok(OwnedValue::Blob(json.data()));
|
||||
}
|
||||
match element_type {
|
||||
ElementType::ARRAY | ElementType::OBJECT => Ok(OwnedValue::Text(Text::json(json_string))),
|
||||
@@ -414,12 +414,12 @@ fn json_string_to_db_type(
|
||||
json_string.remove(json_string.len() - 1);
|
||||
json_string.remove(0);
|
||||
Ok(OwnedValue::Text(Text {
|
||||
value: Rc::new(json_string.into_bytes()),
|
||||
value: json_string.into_bytes(),
|
||||
subtype: TextSubtype::Json,
|
||||
}))
|
||||
} else {
|
||||
Ok(OwnedValue::Text(Text {
|
||||
value: Rc::new(json_string.into_bytes()),
|
||||
value: json_string.into_bytes(),
|
||||
subtype: TextSubtype::Text,
|
||||
}))
|
||||
}
|
||||
@@ -764,7 +764,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_get_json_blob_valid_jsonb() {
|
||||
let binary_json = vec![124, 55, 104, 101, 121, 39, 121, 111];
|
||||
let input = OwnedValue::Blob(Rc::new(binary_json));
|
||||
let input = OwnedValue::Blob(binary_json);
|
||||
let result = get_json(&input, None).unwrap();
|
||||
if let OwnedValue::Text(result_str) = result {
|
||||
assert!(result_str.as_str().contains(r#"{"hey":"yo"}"#));
|
||||
@@ -777,7 +777,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_get_json_blob_invalid_jsonb() {
|
||||
let binary_json: Vec<u8> = vec![0xA2, 0x62, 0x6B, 0x31, 0x62, 0x76]; // Incomplete binary JSON
|
||||
let input = OwnedValue::Blob(Rc::new(binary_json));
|
||||
let input = OwnedValue::Blob(binary_json);
|
||||
let result = get_json(&input, None);
|
||||
println!("{:?}", result);
|
||||
match result {
|
||||
@@ -832,7 +832,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_json_array_blob_invalid() {
|
||||
let blob = Register::OwnedValue(OwnedValue::Blob(Rc::new("1".as_bytes().to_vec())));
|
||||
let blob = Register::OwnedValue(OwnedValue::Blob("1".as_bytes().to_vec()));
|
||||
|
||||
let input = vec![blob];
|
||||
|
||||
|
||||
@@ -3894,7 +3894,7 @@ mod tests {
|
||||
.unwrap();
|
||||
let key = OwnedValue::Integer(*key);
|
||||
let value = ImmutableRecord::from_registers(&[Register::OwnedValue(
|
||||
OwnedValue::Blob(Rc::new(vec![0; *size])),
|
||||
OwnedValue::Blob(vec![0; *size]),
|
||||
)]);
|
||||
tracing::info!("insert key:{}", key);
|
||||
run_until_done(|| cursor.insert(&key, &value, true), pager.deref()).unwrap();
|
||||
@@ -3961,7 +3961,7 @@ mod tests {
|
||||
|
||||
let key = OwnedValue::Integer(key);
|
||||
let value = ImmutableRecord::from_registers(&[Register::OwnedValue(
|
||||
OwnedValue::Blob(Rc::new(vec![0; size])),
|
||||
OwnedValue::Blob(vec![0; size]),
|
||||
)]);
|
||||
run_until_done(|| cursor.insert(&key, &value, true), pager.deref()).unwrap();
|
||||
}
|
||||
@@ -4874,9 +4874,11 @@ mod tests {
|
||||
|
||||
let page = get_page(2);
|
||||
let usable_space = 4096;
|
||||
let record = ImmutableRecord::from_registers(&[Register::OwnedValue(OwnedValue::Blob(
|
||||
Rc::new(vec![0; 3600]),
|
||||
))]);
|
||||
let record =
|
||||
ImmutableRecord::from_registers(&[Register::OwnedValue(OwnedValue::Blob(vec![
|
||||
0;
|
||||
3600
|
||||
]))]);
|
||||
let mut payload: Vec<u8> = Vec::new();
|
||||
fill_cell_payload(
|
||||
page.get_contents().page_type(),
|
||||
|
||||
@@ -34,7 +34,7 @@ pub enum TextSubtype {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Text {
|
||||
pub value: Rc<Vec<u8>>,
|
||||
pub value: Vec<u8>,
|
||||
pub subtype: TextSubtype,
|
||||
}
|
||||
|
||||
@@ -51,14 +51,14 @@ impl Text {
|
||||
|
||||
pub fn new(value: &str) -> Self {
|
||||
Self {
|
||||
value: Rc::new(value.as_bytes().to_vec()),
|
||||
value: value.as_bytes().to_vec(),
|
||||
subtype: TextSubtype::Text,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn json(value: String) -> Self {
|
||||
Self {
|
||||
value: Rc::new(value.into_bytes()),
|
||||
value: value.into_bytes(),
|
||||
subtype: TextSubtype::Json,
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ pub enum OwnedValue {
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
Text(Text),
|
||||
Blob(Rc<Vec<u8>>),
|
||||
Blob(Vec<u8>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@@ -97,7 +97,7 @@ pub struct RawSlice {
|
||||
len: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum RefValue {
|
||||
Null,
|
||||
Integer(i64),
|
||||
@@ -120,7 +120,7 @@ impl OwnedValue {
|
||||
}
|
||||
|
||||
pub fn from_blob(data: Vec<u8>) -> Self {
|
||||
OwnedValue::Blob(std::rc::Rc::new(data))
|
||||
OwnedValue::Blob(data)
|
||||
}
|
||||
|
||||
pub fn to_text(&self) -> Option<&str> {
|
||||
@@ -341,7 +341,7 @@ impl OwnedValue {
|
||||
let Some(blob) = v.to_blob() else {
|
||||
return Ok(OwnedValue::Null);
|
||||
};
|
||||
Ok(OwnedValue::Blob(Rc::new(blob)))
|
||||
Ok(OwnedValue::Blob(blob))
|
||||
}
|
||||
ExtValueType::Error => {
|
||||
let Some(err) = v.to_error_details() else {
|
||||
@@ -742,7 +742,6 @@ impl ImmutableRecord {
|
||||
size_values += value_size;
|
||||
}
|
||||
let mut header_size = size_header;
|
||||
let mut header_bytes_buf: Vec<u8> = Vec::new();
|
||||
if header_size <= 126 {
|
||||
// common case
|
||||
header_size += 1;
|
||||
@@ -879,10 +878,10 @@ impl RefValue {
|
||||
RefValue::Integer(i) => OwnedValue::Integer(*i),
|
||||
RefValue::Float(f) => OwnedValue::Float(*f),
|
||||
RefValue::Text(text_ref) => OwnedValue::Text(Text {
|
||||
value: Rc::new(text_ref.value.to_slice().to_vec()),
|
||||
value: text_ref.value.to_slice().to_vec(),
|
||||
subtype: text_ref.subtype.clone(),
|
||||
}),
|
||||
RefValue::Blob(b) => OwnedValue::Blob(Rc::new(b.to_slice().to_vec())),
|
||||
RefValue::Blob(b) => OwnedValue::Blob(b.to_slice().to_vec()),
|
||||
}
|
||||
}
|
||||
pub fn to_blob(&self) -> Option<&[u8]> {
|
||||
@@ -1457,7 +1456,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_serialize_blob() {
|
||||
let blob = Rc::new(vec![1, 2, 3, 4, 5]);
|
||||
let blob = vec![1, 2, 3, 4, 5];
|
||||
let record = Record::new(vec![OwnedValue::Blob(blob.clone())]);
|
||||
let mut buf = Vec::new();
|
||||
record.serialize(&mut buf);
|
||||
|
||||
@@ -672,7 +672,7 @@ pub fn insn_to_str(
|
||||
0,
|
||||
*dest as i32,
|
||||
0,
|
||||
OwnedValue::Blob(Rc::new(value.clone())),
|
||||
OwnedValue::Blob(value.clone()),
|
||||
0,
|
||||
format!(
|
||||
"r[{}]={} (len={})",
|
||||
|
||||
102
core/vdbe/mod.rs
102
core/vdbe/mod.rs
@@ -50,7 +50,7 @@ use crate::util::{
|
||||
use crate::vdbe::builder::CursorType;
|
||||
use crate::vdbe::insn::Insn;
|
||||
use crate::vector::{vector32, vector64, vector_distance_cos, vector_extract};
|
||||
use crate::{bail_constraint_error, info, CheckpointStatus};
|
||||
use crate::{bail_constraint_error, info, CheckpointStatus, RefValue};
|
||||
#[cfg(feature = "json")]
|
||||
use crate::{
|
||||
function::JsonFunc, json::get_json, json::is_json_valid, json::json_array,
|
||||
@@ -1180,17 +1180,38 @@ impl Program {
|
||||
);
|
||||
let cursor = cursor.as_btree_mut();
|
||||
let record = cursor.record();
|
||||
if let Some(record) = record.as_ref() {
|
||||
let value = if let Some(record) = record.as_ref() {
|
||||
if cursor.get_null_flag() {
|
||||
OwnedValue::Null
|
||||
RefValue::Null
|
||||
} else {
|
||||
record.get_value(*column).to_owned()
|
||||
record.get_value(*column).clone()
|
||||
}
|
||||
} else {
|
||||
OwnedValue::Null
|
||||
}
|
||||
RefValue::Null
|
||||
};
|
||||
value
|
||||
};
|
||||
state.registers[*dest] = Register::OwnedValue(value);
|
||||
// If we are copying a text/blob, let's try to simply update size of text if we need to allocate more and reuse.
|
||||
match (&value, &mut state.registers[*dest]) {
|
||||
(
|
||||
RefValue::Text(text_ref),
|
||||
Register::OwnedValue(OwnedValue::Text(text_reg)),
|
||||
) => {
|
||||
text_reg.value.clear();
|
||||
text_reg.value.extend_from_slice(text_ref.value.to_slice());
|
||||
}
|
||||
(
|
||||
RefValue::Blob(raw_slice),
|
||||
Register::OwnedValue(OwnedValue::Blob(blob_reg)),
|
||||
) => {
|
||||
blob_reg.clear();
|
||||
blob_reg.extend_from_slice(raw_slice.to_slice());
|
||||
}
|
||||
_ => {
|
||||
let reg = &mut state.registers[*dest];
|
||||
*reg = Register::OwnedValue(value.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
CursorType::Sorter => {
|
||||
let record = {
|
||||
@@ -1436,8 +1457,7 @@ impl Program {
|
||||
state.pc += 1;
|
||||
}
|
||||
Insn::Blob { value, dest } => {
|
||||
state.registers[*dest] =
|
||||
Register::OwnedValue(OwnedValue::Blob(Rc::new(value.clone())));
|
||||
state.registers[*dest] = Register::OwnedValue(OwnedValue::Blob(value.clone()));
|
||||
state.pc += 1;
|
||||
}
|
||||
Insn::RowId { cursor_id, dest } => {
|
||||
@@ -3908,7 +3928,7 @@ fn exec_randomblob(reg: &OwnedValue) -> OwnedValue {
|
||||
|
||||
let mut blob: Vec<u8> = vec![0; length];
|
||||
getrandom::getrandom(&mut blob).expect("Failed to generate random blob");
|
||||
OwnedValue::Blob(Rc::new(blob))
|
||||
OwnedValue::Blob(blob)
|
||||
}
|
||||
|
||||
fn exec_quote(value: &OwnedValue) -> OwnedValue {
|
||||
@@ -4060,7 +4080,7 @@ fn exec_instr(reg: &OwnedValue, pattern: &OwnedValue) -> OwnedValue {
|
||||
if let (OwnedValue::Blob(reg), OwnedValue::Blob(pattern)) = (reg, pattern) {
|
||||
let result = reg
|
||||
.windows(pattern.len())
|
||||
.position(|window| window == **pattern)
|
||||
.position(|window| window == *pattern)
|
||||
.map_or(0, |i| i + 1);
|
||||
return OwnedValue::Integer(result as i64);
|
||||
}
|
||||
@@ -4117,7 +4137,7 @@ fn exec_unhex(reg: &OwnedValue, ignored_chars: Option<&OwnedValue>) -> OwnedValu
|
||||
OwnedValue::Null => OwnedValue::Null,
|
||||
_ => match ignored_chars {
|
||||
None => match hex::decode(reg.to_string()) {
|
||||
Ok(bytes) => OwnedValue::Blob(Rc::new(bytes)),
|
||||
Ok(bytes) => OwnedValue::Blob(bytes),
|
||||
Err(_) => OwnedValue::Null,
|
||||
},
|
||||
Some(ignore) => match ignore {
|
||||
@@ -4129,7 +4149,7 @@ fn exec_unhex(reg: &OwnedValue, ignored_chars: Option<&OwnedValue>) -> OwnedValu
|
||||
.trim_end_matches(|x| pat.contains(x))
|
||||
.to_string();
|
||||
match hex::decode(trimmed) {
|
||||
Ok(bytes) => OwnedValue::Blob(Rc::new(bytes)),
|
||||
Ok(bytes) => OwnedValue::Blob(bytes),
|
||||
Err(_) => OwnedValue::Null,
|
||||
}
|
||||
}
|
||||
@@ -4240,7 +4260,7 @@ fn exec_zeroblob(req: &OwnedValue) -> OwnedValue {
|
||||
OwnedValue::Text(s) => s.as_str().parse().unwrap_or(0),
|
||||
_ => 0,
|
||||
};
|
||||
OwnedValue::Blob(Rc::new(vec![0; length.max(0) as usize]))
|
||||
OwnedValue::Blob(vec![0; length.max(0) as usize])
|
||||
}
|
||||
|
||||
// exec_if returns whether you should jump
|
||||
@@ -4264,7 +4284,7 @@ fn exec_cast(value: &OwnedValue, datatype: &str) -> OwnedValue {
|
||||
// Convert to TEXT first, then interpret as BLOB
|
||||
// TODO: handle encoding
|
||||
let text = value.to_string();
|
||||
OwnedValue::Blob(Rc::new(text.into_bytes()))
|
||||
OwnedValue::Blob(text.into_bytes())
|
||||
}
|
||||
// TEXT To cast a BLOB value to TEXT, the sequence of bytes that make up the BLOB is interpreted as text encoded using the database encoding.
|
||||
// Casting an INTEGER or REAL value into TEXT renders the value as if via sqlite3_snprintf() except that the resulting TEXT uses the encoding of the database connection.
|
||||
@@ -4493,7 +4513,7 @@ mod tests {
|
||||
let expected_len = OwnedValue::Integer(7);
|
||||
assert_eq!(exec_length(&input_float), expected_len);
|
||||
|
||||
let expected_blob = OwnedValue::Blob(Rc::new("example".as_bytes().to_vec()));
|
||||
let expected_blob = OwnedValue::Blob("example".as_bytes().to_vec());
|
||||
let expected_len = OwnedValue::Integer(7);
|
||||
assert_eq!(exec_length(&expected_blob), expected_len);
|
||||
}
|
||||
@@ -4531,7 +4551,7 @@ mod tests {
|
||||
let expected: OwnedValue = OwnedValue::build_text("text");
|
||||
assert_eq!(exec_typeof(&input), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new("limbo".as_bytes().to_vec()));
|
||||
let input = OwnedValue::Blob("limbo".as_bytes().to_vec());
|
||||
let expected: OwnedValue = OwnedValue::build_text("blob");
|
||||
assert_eq!(exec_typeof(&input), expected);
|
||||
}
|
||||
@@ -4565,7 +4585,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(exec_unicode(&OwnedValue::Null), OwnedValue::Null);
|
||||
assert_eq!(
|
||||
exec_unicode(&OwnedValue::Blob(Rc::new("example".as_bytes().to_vec()))),
|
||||
exec_unicode(&OwnedValue::Blob("example".as_bytes().to_vec())),
|
||||
OwnedValue::Integer(101)
|
||||
);
|
||||
}
|
||||
@@ -4725,11 +4745,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_unhex() {
|
||||
let input = OwnedValue::build_text("6f");
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![0x6f]));
|
||||
let expected = OwnedValue::Blob(vec![0x6f]);
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::build_text("6f");
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![0x6f]));
|
||||
let expected = OwnedValue::Blob(vec![0x6f]);
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::build_text("611");
|
||||
@@ -4737,7 +4757,7 @@ mod tests {
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::build_text("");
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
let expected = OwnedValue::Blob(vec![]);
|
||||
assert_eq!(exec_unhex(&input, None), expected);
|
||||
|
||||
let input = OwnedValue::build_text("61x");
|
||||
@@ -5124,23 +5144,23 @@ mod tests {
|
||||
let expected = OwnedValue::Integer(3);
|
||||
assert_eq!(exec_instr(&input, &pattern), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(vec![1, 2, 3, 4, 5]));
|
||||
let pattern = OwnedValue::Blob(Rc::new(vec![3, 4]));
|
||||
let input = OwnedValue::Blob(vec![1, 2, 3, 4, 5]);
|
||||
let pattern = OwnedValue::Blob(vec![3, 4]);
|
||||
let expected = OwnedValue::Integer(3);
|
||||
assert_eq!(exec_instr(&input, &pattern), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(vec![1, 2, 3, 4, 5]));
|
||||
let pattern = OwnedValue::Blob(Rc::new(vec![3, 2]));
|
||||
let input = OwnedValue::Blob(vec![1, 2, 3, 4, 5]);
|
||||
let pattern = OwnedValue::Blob(vec![3, 2]);
|
||||
let expected = OwnedValue::Integer(0);
|
||||
assert_eq!(exec_instr(&input, &pattern), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(vec![0x61, 0x62, 0x63, 0x64, 0x65]));
|
||||
let input = OwnedValue::Blob(vec![0x61, 0x62, 0x63, 0x64, 0x65]);
|
||||
let pattern = OwnedValue::build_text("cd");
|
||||
let expected = OwnedValue::Integer(3);
|
||||
assert_eq!(exec_instr(&input, &pattern), expected);
|
||||
|
||||
let input = OwnedValue::build_text("abcde");
|
||||
let pattern = OwnedValue::Blob(Rc::new(vec![0x63, 0x64]));
|
||||
let pattern = OwnedValue::Blob(vec![0x63, 0x64]);
|
||||
let expected = OwnedValue::Integer(3);
|
||||
assert_eq!(exec_instr(&input, &pattern), expected);
|
||||
}
|
||||
@@ -5191,19 +5211,19 @@ mod tests {
|
||||
let expected = Some(OwnedValue::Integer(0));
|
||||
assert_eq!(exec_sign(&input), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(b"abc".to_vec()));
|
||||
let input = OwnedValue::Blob(b"abc".to_vec());
|
||||
let expected = Some(OwnedValue::Null);
|
||||
assert_eq!(exec_sign(&input), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(b"42".to_vec()));
|
||||
let input = OwnedValue::Blob(b"42".to_vec());
|
||||
let expected = Some(OwnedValue::Integer(1));
|
||||
assert_eq!(exec_sign(&input), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(b"-42".to_vec()));
|
||||
let input = OwnedValue::Blob(b"-42".to_vec());
|
||||
let expected = Some(OwnedValue::Integer(-1));
|
||||
assert_eq!(exec_sign(&input), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(b"0".to_vec()));
|
||||
let input = OwnedValue::Blob(b"0".to_vec());
|
||||
let expected = Some(OwnedValue::Integer(0));
|
||||
assert_eq!(exec_sign(&input), expected);
|
||||
|
||||
@@ -5215,39 +5235,39 @@ mod tests {
|
||||
#[test]
|
||||
fn test_exec_zeroblob() {
|
||||
let input = OwnedValue::Integer(0);
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
let expected = OwnedValue::Blob(vec![]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::Null;
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
let expected = OwnedValue::Blob(vec![]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::Integer(4);
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![0; 4]));
|
||||
let expected = OwnedValue::Blob(vec![0; 4]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::Integer(-1);
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
let expected = OwnedValue::Blob(vec![]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::build_text("5");
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![0; 5]));
|
||||
let expected = OwnedValue::Blob(vec![0; 5]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::build_text("-5");
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
let expected = OwnedValue::Blob(vec![]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::build_text("text");
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
let expected = OwnedValue::Blob(vec![]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::Float(2.6);
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![0; 2]));
|
||||
let expected = OwnedValue::Blob(vec![0; 2]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
|
||||
let input = OwnedValue::Blob(Rc::new(vec![1]));
|
||||
let expected = OwnedValue::Blob(Rc::new(vec![]));
|
||||
let input = OwnedValue::Blob(vec![1]);
|
||||
let expected = OwnedValue::Blob(vec![]);
|
||||
assert_eq!(exec_zeroblob(&input), expected);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user