From d8fb321b1697720b20318d8007d9ce39ee185202 Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Tue, 8 Jul 2025 10:27:48 +0400 Subject: [PATCH 1/2] treat ImmutableRecord as Value::Blob --- core/types.rs | 40 ++++++++++++++++++++++++++++++---------- core/vdbe/mod.rs | 6 +++++- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/core/types.rs b/core/types.rs index e8dd9e588..a2263fa76 100644 --- a/core/types.rs +++ b/core/types.rs @@ -231,6 +231,20 @@ impl Value { } } + pub fn as_blob(&self) -> &Vec { + match self { + Value::Blob(b) => b, + _ => panic!("as_blob must be called only for Value::Blob"), + } + } + + pub fn as_blob_mut(&mut self) -> &mut Vec { + match self { + Value::Blob(b) => b, + _ => panic!("as_blob must be called only for Value::Blob"), + } + } + pub fn from_text(text: &str) -> Self { Value::Text(Text::new(text)) } @@ -738,7 +752,9 @@ pub struct ImmutableRecord { // We have to be super careful with this buffer since we make values point to the payload we need to take care reallocations // happen in a controlled manner. If we realocate with values that should be correct, they will now point to undefined data. // We don't use pin here because it would make it imposible to reuse the buffer if we need to push a new record in the same struct. - payload: Vec, + // + // payload is the Vec but in order to use Register which holds ImmutableRecord as a Value - we store Vec as Value::Blob + payload: Value, pub values: Vec, recreating: bool, } @@ -828,7 +844,7 @@ impl<'a> AppendWriter<'a> { impl ImmutableRecord { pub fn new(payload_capacity: usize, value_capacity: usize) -> Self { Self { - payload: Vec::with_capacity(payload_capacity), + payload: Value::Blob(Vec::with_capacity(payload_capacity)), values: Vec::with_capacity(value_capacity), recreating: false, } @@ -977,7 +993,7 @@ impl ImmutableRecord { writer.assert_finish_capacity(); Self { - payload: buf, + payload: Value::Blob(buf), values, recreating: false, } @@ -985,7 +1001,7 @@ impl ImmutableRecord { pub fn start_serialization(&mut self, payload: &[u8]) { self.recreating = true; - self.payload.extend_from_slice(payload); + self.payload.as_blob_mut().extend_from_slice(payload); } pub fn end_serialization(&mut self) { assert!(self.recreating); @@ -998,15 +1014,19 @@ impl ImmutableRecord { } pub fn invalidate(&mut self) { - self.payload.clear(); + self.payload.as_blob_mut().clear(); self.values.clear(); } pub fn is_invalidated(&self) -> bool { - self.payload.is_empty() + self.payload.as_blob().is_empty() } pub fn get_payload(&self) -> &[u8] { + &self.payload.as_blob() + } + + pub fn as_blob_value(&self) -> &Value { &self.payload } } @@ -1042,20 +1062,20 @@ impl Clone for ImmutableRecord { RefValue::Float(f) => RefValue::Float(*f), RefValue::Text(text_ref) => { // let's update pointer - let ptr_start = self.payload.as_ptr() as usize; + let ptr_start = self.payload.as_blob().as_ptr() as usize; let ptr_end = text_ref.value.data as usize; let len = ptr_end - ptr_start; - let new_ptr = unsafe { new_payload.as_ptr().add(len) }; + let new_ptr = unsafe { new_payload.as_blob().as_ptr().add(len) }; RefValue::Text(TextRef { value: RawSlice::new(new_ptr, text_ref.value.len), subtype: text_ref.subtype.clone(), }) } RefValue::Blob(raw_slice) => { - let ptr_start = self.payload.as_ptr() as usize; + let ptr_start = self.payload.as_blob().as_ptr() as usize; let ptr_end = raw_slice.data as usize; let len = ptr_end - ptr_start; - let new_ptr = unsafe { new_payload.as_ptr().add(len) }; + let new_ptr = unsafe { new_payload.as_blob().as_ptr().add(len) }; RefValue::Blob(RawSlice::new(new_ptr, raw_slice.len)) } }; diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index e2195a853..3750fcfec 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -334,7 +334,11 @@ impl Register { pub fn get_owned_value(&self) -> &Value { match self { Register::Value(v) => v, - _ => unreachable!(), + Register::Record(r) => { + assert!(!r.is_invalidated()); + r.as_blob_value() + } + _ => panic!("register holds unexpected value: {:?}", self), } } } From 29422542cd003004b337d9e0c6d1c3a6b489df19 Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Tue, 8 Jul 2025 10:31:40 +0400 Subject: [PATCH 2/2] fix clippy --- core/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/types.rs b/core/types.rs index a2263fa76..4ca43dad9 100644 --- a/core/types.rs +++ b/core/types.rs @@ -1023,7 +1023,7 @@ impl ImmutableRecord { } pub fn get_payload(&self) -> &[u8] { - &self.payload.as_blob() + self.payload.as_blob() } pub fn as_blob_value(&self) -> &Value {