Extract raw bytes for a variable-length column. Returns `None` if null. Reads two entries from the offset table to determine start and length.
(
&self,
tuple: &'a [u8],
col_idx: usize,
)
| 148 | /// |
| 149 | /// Reads two entries from the offset table to determine start and length. |
| 150 | pub fn extract_variable_raw<'a>( |
| 151 | &self, |
| 152 | tuple: &'a [u8], |
| 153 | col_idx: usize, |
| 154 | ) -> Result<Option<&'a [u8]>, StrictError> { |
| 155 | self.check_bounds(col_idx)?; |
| 156 | self.check_min_size(tuple)?; |
| 157 | |
| 158 | if self.is_null_unchecked(tuple, col_idx) { |
| 159 | return Ok(None); |
| 160 | } |
| 161 | |
| 162 | let var_idx = self.var_table_index[col_idx].ok_or(StrictError::TypeMismatch { |
| 163 | column: self.schema.columns[col_idx].name.clone(), |
| 164 | expected: self.schema.columns[col_idx].column_type, |
| 165 | })?; |
| 166 | |
| 167 | let table_start = self.header_size + self.fixed_section_size; |
| 168 | let entry_pos = table_start + var_idx * 4; |
| 169 | let next_pos = entry_pos + 4; |
| 170 | |
| 171 | if next_pos + 4 > tuple.len() { |
| 172 | return Err(StrictError::TruncatedTuple { |
| 173 | expected: next_pos + 4, |
| 174 | got: tuple.len(), |
| 175 | }); |
| 176 | } |
| 177 | |
| 178 | // Safety: bounds checked above — entry_pos..+4 and next_pos..+4 are within tuple. |
| 179 | let offset = u32::from_le_bytes( |
| 180 | tuple[entry_pos..entry_pos + 4] |
| 181 | .try_into() |
| 182 | .expect("4-byte slice from bounds-checked range"), |
| 183 | ); |
| 184 | let next_offset = u32::from_le_bytes( |
| 185 | tuple[next_pos..next_pos + 4] |
| 186 | .try_into() |
| 187 | .expect("4-byte slice from bounds-checked range"), |
| 188 | ); |
| 189 | |
| 190 | let var_data_start = table_start + (self.var_count + 1) * 4; |
| 191 | let abs_start = var_data_start + offset as usize; |
| 192 | let abs_end = var_data_start + next_offset as usize; |
| 193 | |
| 194 | if abs_end > tuple.len() { |
| 195 | return Err(StrictError::CorruptOffset { |
| 196 | offset: next_offset, |
| 197 | len: tuple.len(), |
| 198 | }); |
| 199 | } |
| 200 | |
| 201 | Ok(Some(&tuple[abs_start..abs_end])) |
| 202 | } |
| 203 | |
| 204 | /// Extract a column value as a `Value`, performing type-aware decoding. |
| 205 | /// |