1use crate::buffer::ReadBuffer;
9use crate::constants::{length, OracleType};
10use crate::dbobject::DbObject;
11use crate::error::{Error, Result};
12use crate::statement::ColumnInfo;
13use crate::types::{
14 decode_binary_double, decode_binary_float, decode_oracle_date, decode_oracle_number,
15 decode_oracle_timestamp, decode_rowid, LobValue, OracleDate, OracleNumber, OracleTimestamp,
16 OracleVector, RefCursor, RowId,
17};
18
19#[derive(Debug, Clone)]
53pub enum Value {
54 Null,
56 String(String),
58 Bytes(Vec<u8>),
60 Integer(i64),
62 Float(f64),
64 Number(OracleNumber),
66 Date(OracleDate),
68 Timestamp(OracleTimestamp),
70 RowId(RowId),
72 Boolean(bool),
74 Lob(LobValue),
76 Json(serde_json::Value),
78 Vector(OracleVector),
80 Cursor(RefCursor),
83 Collection(DbObject),
86}
87
88impl Value {
89 pub fn is_null(&self) -> bool {
91 matches!(self, Value::Null)
92 }
93
94 pub fn as_str(&self) -> Option<&str> {
96 match self {
97 Value::String(s) => Some(s),
98 _ => None,
99 }
100 }
101
102 pub fn as_i64(&self) -> Option<i64> {
104 match self {
105 Value::Integer(i) => Some(*i),
106 Value::Float(f) => Some(*f as i64),
107 Value::Number(n) => n.to_i64().ok(),
108 _ => None,
109 }
110 }
111
112 pub fn as_f64(&self) -> Option<f64> {
114 match self {
115 Value::Float(f) => Some(*f),
116 Value::Integer(i) => Some(*i as f64),
117 Value::Number(n) => n.to_f64().ok(),
118 _ => None,
119 }
120 }
121
122 pub fn as_bytes(&self) -> Option<&[u8]> {
124 match self {
125 Value::Bytes(b) => Some(b),
126 Value::String(s) => Some(s.as_bytes()),
127 _ => None,
128 }
129 }
130
131 pub fn as_bool(&self) -> Option<bool> {
133 match self {
134 Value::Boolean(b) => Some(*b),
135 Value::Integer(i) => Some(*i != 0),
136 _ => None,
137 }
138 }
139
140 pub fn as_date(&self) -> Option<&OracleDate> {
142 match self {
143 Value::Date(d) => Some(d),
144 _ => None,
145 }
146 }
147
148 pub fn as_timestamp(&self) -> Option<&OracleTimestamp> {
150 match self {
151 Value::Timestamp(ts) => Some(ts),
152 _ => None,
153 }
154 }
155
156 pub fn as_json(&self) -> Option<&serde_json::Value> {
158 match self {
159 Value::Json(j) => Some(j),
160 _ => None,
161 }
162 }
163
164 pub fn as_vector(&self) -> Option<&OracleVector> {
166 match self {
167 Value::Vector(v) => Some(v),
168 _ => None,
169 }
170 }
171
172 pub fn as_cursor(&self) -> Option<&RefCursor> {
174 match self {
175 Value::Cursor(cursor) => Some(cursor),
176 _ => None,
177 }
178 }
179
180 pub fn as_cursor_id(&self) -> Option<u16> {
182 match self {
183 Value::Cursor(cursor) => Some(cursor.cursor_id()),
184 _ => None,
185 }
186 }
187
188 pub fn as_collection(&self) -> Option<&DbObject> {
190 match self {
191 Value::Collection(obj) => Some(obj),
192 _ => None,
193 }
194 }
195}
196
197impl From<i32> for Value {
202 fn from(v: i32) -> Self {
203 Value::Integer(v as i64)
204 }
205}
206
207impl From<f32> for Value {
208 fn from(v: f32) -> Self {
209 Value::Float(v as f64)
210 }
211}
212
213impl From<&[u8]> for Value {
214 fn from(v: &[u8]) -> Self {
215 Value::Bytes(v.to_vec())
216 }
217}
218
219impl<T: Into<Value>> From<Option<T>> for Value {
220 fn from(v: Option<T>) -> Self {
221 match v {
222 Some(inner) => inner.into(),
223 None => Value::Null,
224 }
225 }
226}
227
228impl From<serde_json::Value> for Value {
229 fn from(v: serde_json::Value) -> Self {
230 Value::Json(v)
231 }
232}
233
234impl From<OracleVector> for Value {
235 fn from(v: OracleVector) -> Self {
236 Value::Vector(v)
237 }
238}
239
240impl From<Vec<f32>> for Value {
241 fn from(v: Vec<f32>) -> Self {
242 Value::Vector(OracleVector::float32(v))
243 }
244}
245
246impl From<Vec<f64>> for Value {
247 fn from(v: Vec<f64>) -> Self {
248 Value::Vector(OracleVector::float64(v))
249 }
250}
251
252impl From<DbObject> for Value {
253 fn from(v: DbObject) -> Self {
254 Value::Collection(v)
255 }
256}
257
258impl std::fmt::Display for Value {
259 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
260 match self {
261 Value::Null => write!(f, "NULL"),
262 Value::String(s) => write!(f, "{}", s),
263 Value::Bytes(b) => write!(f, "<{} bytes>", b.len()),
264 Value::Integer(i) => write!(f, "{}", i),
265 Value::Float(fl) => write!(f, "{}", fl),
266 Value::Number(n) => write!(f, "{}", n.as_str()),
267 Value::Date(d) => write!(
268 f,
269 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}",
270 d.year, d.month, d.day, d.hour, d.minute, d.second
271 ),
272 Value::Timestamp(ts) => {
273 write!(
274 f,
275 "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:06}",
276 ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second, ts.microsecond
277 )?;
278 if ts.has_timezone() {
279 write!(f, " {:+03}:{:02}", ts.tz_hour_offset, ts.tz_minute_offset)?;
280 }
281 Ok(())
282 }
283 Value::RowId(r) => write!(f, "{}", r),
284 Value::Boolean(b) => write!(f, "{}", b),
285 Value::Lob(lob) => match lob {
286 LobValue::Null => write!(f, "NULL"),
287 LobValue::Empty => write!(f, "<empty LOB>"),
288 LobValue::Inline(data) => write!(f, "<LOB: {} bytes inline>", data.len()),
289 LobValue::Locator(loc) => {
290 write!(f, "<LOB: {} bytes, locator>", loc.size())
291 }
292 },
293 Value::Json(json) => write!(f, "{}", json),
294 Value::Vector(vec) => write!(f, "<VECTOR: {} dimensions>", vec.dimensions()),
295 Value::Cursor(cursor) => write!(f, "<CURSOR: id={}, {} columns>", cursor.cursor_id(), cursor.column_count()),
296 Value::Collection(obj) => {
297 if obj.is_collection {
298 write!(f, "<COLLECTION {}: {} elements>", obj.type_name, obj.elements.len())
299 } else {
300 write!(f, "<OBJECT {}: {} attributes>", obj.type_name, obj.values.len())
301 }
302 }
303 }
304 }
305}
306
307#[derive(Debug, Clone)]
334pub struct Row {
335 values: Vec<Value>,
337 column_names: Option<Vec<String>>,
339}
340
341impl Row {
342 pub fn new(values: Vec<Value>) -> Self {
344 Self {
345 values,
346 column_names: None,
347 }
348 }
349
350 pub fn with_names(values: Vec<Value>, names: Vec<String>) -> Self {
352 Self {
353 values,
354 column_names: Some(names),
355 }
356 }
357
358 pub fn len(&self) -> usize {
360 self.values.len()
361 }
362
363 pub fn is_empty(&self) -> bool {
365 self.values.is_empty()
366 }
367
368 pub fn get(&self, index: usize) -> Option<&Value> {
370 self.values.get(index)
371 }
372
373 pub fn get_by_name(&self, name: &str) -> Option<&Value> {
375 let names = self.column_names.as_ref()?;
376 let index = names.iter().position(|n| n.eq_ignore_ascii_case(name))?;
377 self.values.get(index)
378 }
379
380 pub fn values(&self) -> &[Value] {
382 &self.values
383 }
384
385 pub fn into_values(self) -> Vec<Value> {
387 self.values
388 }
389
390 pub fn get_string(&self, index: usize) -> Option<&str> {
392 self.get(index).and_then(Value::as_str)
393 }
394
395 pub fn get_i64(&self, index: usize) -> Option<i64> {
397 self.get(index).and_then(Value::as_i64)
398 }
399
400 pub fn get_f64(&self, index: usize) -> Option<f64> {
402 self.get(index).and_then(Value::as_f64)
403 }
404
405 pub fn is_null(&self, index: usize) -> bool {
407 self.get(index).map(Value::is_null).unwrap_or(true)
408 }
409}
410
411impl std::ops::Index<usize> for Row {
412 type Output = Value;
413
414 fn index(&self, index: usize) -> &Self::Output {
415 &self.values[index]
416 }
417}
418
419pub struct RowDataDecoder<'a> {
421 columns: &'a [ColumnInfo],
422 bit_vector: Option<Vec<u8>>,
423}
424
425impl<'a> RowDataDecoder<'a> {
426 pub fn new(columns: &'a [ColumnInfo]) -> Self {
428 Self {
429 columns,
430 bit_vector: None,
431 }
432 }
433
434 pub fn set_bit_vector(&mut self, bit_vector: Vec<u8>) {
436 self.bit_vector = Some(bit_vector);
437 }
438
439 pub fn clear_bit_vector(&mut self) {
441 self.bit_vector = None;
442 }
443
444 fn is_duplicate(&self, column_index: usize) -> bool {
446 match &self.bit_vector {
447 Some(bv) => {
448 let byte_num = column_index / 8;
449 let bit_num = column_index % 8;
450 if byte_num < bv.len() {
451 (bv[byte_num] & (1 << bit_num)) == 0
452 } else {
453 false
454 }
455 }
456 None => false,
457 }
458 }
459
460 pub fn decode_row(
462 &self,
463 buf: &mut ReadBuffer,
464 previous_row: Option<&Row>,
465 ) -> Result<Row> {
466 let mut values = Vec::with_capacity(self.columns.len());
467
468 for (index, column) in self.columns.iter().enumerate() {
469 let value = if self.is_duplicate(index) {
470 previous_row
472 .and_then(|r| r.get(index))
473 .cloned()
474 .unwrap_or(Value::Null)
475 } else {
476 self.decode_column_value(buf, column)?
477 };
478 values.push(value);
479 }
480
481 let names: Vec<String> = self.columns.iter().map(|c| c.name.clone()).collect();
482 Ok(Row::with_names(values, names))
483 }
484
485 fn decode_column_value(&self, buf: &mut ReadBuffer, column: &ColumnInfo) -> Result<Value> {
487 if column.buffer_size == 0 {
489 match column.oracle_type {
490 OracleType::Long | OracleType::LongRaw | OracleType::Urowid => {
491 }
493 _ => return Ok(Value::Null),
494 }
495 }
496
497 match column.oracle_type {
499 OracleType::Varchar | OracleType::Char | OracleType::Long => {
500 self.decode_string(buf)
501 }
502 OracleType::Number | OracleType::BinaryInteger => {
503 self.decode_number(buf)
504 }
505 OracleType::Date => self.decode_date(buf),
506 OracleType::Timestamp | OracleType::TimestampLtz => {
507 self.decode_timestamp(buf, false)
508 }
509 OracleType::TimestampTz => self.decode_timestamp(buf, true),
510 OracleType::Raw | OracleType::LongRaw => self.decode_raw(buf),
511 OracleType::BinaryFloat => self.decode_binary_float(buf),
512 OracleType::BinaryDouble => self.decode_binary_double(buf),
513 OracleType::Rowid => self.decode_rowid(buf),
514 OracleType::Urowid => self.decode_urowid(buf),
515 OracleType::Boolean => self.decode_boolean(buf),
516 _ => {
517 self.decode_raw(buf)
519 }
520 }
521 }
522
523 fn read_oracle_slice(&self, buf: &mut ReadBuffer) -> Result<Option<Vec<u8>>> {
525 if buf.remaining() == 0 {
526 return Ok(None);
527 }
528
529 let length = buf.read_u8()?;
530
531 if length == 0 || length == length::NULL_INDICATOR {
533 return Ok(None);
534 }
535
536 if length == length::LONG_INDICATOR {
538 return self.read_chunked_data(buf);
539 }
540
541 let data = buf.read_bytes_vec(length as usize)?;
543 Ok(Some(data))
544 }
545
546 fn read_chunked_data(&self, buf: &mut ReadBuffer) -> Result<Option<Vec<u8>>> {
548 let mut result = Vec::new();
549
550 loop {
551 let chunk_len = buf.read_ub4()?;
552 if chunk_len == 0 {
553 break;
554 }
555 let chunk = buf.read_bytes_vec(chunk_len as usize)?;
556 result.extend_from_slice(&chunk);
557 }
558
559 if result.is_empty() {
560 Ok(None)
561 } else {
562 Ok(Some(result))
563 }
564 }
565
566 fn decode_string(&self, buf: &mut ReadBuffer) -> Result<Value> {
568 match self.read_oracle_slice(buf)? {
569 None => Ok(Value::Null),
570 Some(data) => {
571 let s = String::from_utf8(data).map_err(|e| {
572 Error::DataConversionError(format!("Invalid UTF-8 in string: {}", e))
573 })?;
574 Ok(Value::String(s))
575 }
576 }
577 }
578
579 fn decode_number(&self, buf: &mut ReadBuffer) -> Result<Value> {
581 match self.read_oracle_slice(buf)? {
582 None => Ok(Value::Null),
583 Some(data) => {
584 let num = decode_oracle_number(&data)?;
585 if num.is_integer {
587 if let Ok(i) = num.to_i64() {
588 return Ok(Value::Integer(i));
589 }
590 }
591 Ok(Value::Number(num))
593 }
594 }
595 }
596
597 fn decode_date(&self, buf: &mut ReadBuffer) -> Result<Value> {
599 match self.read_oracle_slice(buf)? {
600 None => Ok(Value::Null),
601 Some(data) => {
602 let date = decode_oracle_date(&data)?;
603 Ok(Value::Date(date))
604 }
605 }
606 }
607
608 fn decode_timestamp(&self, buf: &mut ReadBuffer, _with_tz: bool) -> Result<Value> {
610 match self.read_oracle_slice(buf)? {
611 None => Ok(Value::Null),
612 Some(data) => {
613 let ts = decode_oracle_timestamp(&data)?;
614 Ok(Value::Timestamp(ts))
615 }
616 }
617 }
618
619 fn decode_raw(&self, buf: &mut ReadBuffer) -> Result<Value> {
621 match self.read_oracle_slice(buf)? {
622 None => Ok(Value::Null),
623 Some(data) => Ok(Value::Bytes(data)),
624 }
625 }
626
627 fn decode_binary_float(&self, buf: &mut ReadBuffer) -> Result<Value> {
629 match self.read_oracle_slice(buf)? {
630 None => Ok(Value::Null),
631 Some(data) => {
632 let f = decode_binary_float(&data);
633 Ok(Value::Float(f as f64))
634 }
635 }
636 }
637
638 fn decode_binary_double(&self, buf: &mut ReadBuffer) -> Result<Value> {
640 match self.read_oracle_slice(buf)? {
641 None => Ok(Value::Null),
642 Some(data) => {
643 let f = decode_binary_double(&data);
644 Ok(Value::Float(f))
645 }
646 }
647 }
648
649 fn decode_rowid(&self, buf: &mut ReadBuffer) -> Result<Value> {
651 let length = buf.read_u8()?;
652
653 if length == 0 || length == length::NULL_INDICATOR {
654 return Ok(Value::Null);
655 }
656
657 let rba = buf.read_ub4()?;
659 let partition_id = buf.read_ub2()?;
660 buf.skip(1)?; let block_num = buf.read_ub4()?;
662 let slot_num = buf.read_ub2()?;
663
664 let rowid = RowId::new(rba, partition_id as u16, block_num, slot_num as u16);
665 Ok(Value::RowId(rowid))
666 }
667
668 fn decode_urowid(&self, buf: &mut ReadBuffer) -> Result<Value> {
670 match self.read_oracle_slice(buf)? {
672 None => Ok(Value::Null),
673 Some(data) => {
674 if data.is_empty() {
676 return Ok(Value::Null);
677 }
678
679 if data[0] == 1 && data.len() >= 13 {
681 let rowid = decode_rowid(&data)?;
683 Ok(Value::RowId(rowid))
684 } else {
685 let s = String::from_utf8_lossy(&data[1..]).to_string();
687 Ok(Value::String(s))
688 }
689 }
690 }
691 }
692
693 fn decode_boolean(&self, buf: &mut ReadBuffer) -> Result<Value> {
695 match self.read_oracle_slice(buf)? {
696 None => Ok(Value::Null),
697 Some(data) => {
698 let b = data.last().copied().unwrap_or(0) == 1;
700 Ok(Value::Boolean(b))
701 }
702 }
703 }
704}
705
706pub fn parse_row_header(buf: &mut ReadBuffer) -> Result<Option<Vec<u8>>> {
717 buf.skip(1)?; buf.skip_ub2()?; buf.skip_ub4()?; buf.skip_ub4()?; buf.skip_ub2()?; let bit_vector_len = buf.read_ub4()? as usize;
725 let bit_vector = if bit_vector_len > 0 {
726 buf.skip(1)?; let data = buf.read_bytes_vec(bit_vector_len - 1)?;
728 Some(data)
729 } else {
730 None
731 };
732
733 let rxhrid_len = buf.read_ub4()? as usize;
735 if rxhrid_len > 0 {
736 loop {
738 let chunk_len = buf.read_ub4()? as usize;
739 if chunk_len == 0 {
740 break;
741 }
742 buf.skip(chunk_len)?;
743 }
744 }
745
746 Ok(bit_vector)
747}
748
749#[cfg(test)]
750mod tests {
751 use super::*;
752 use crate::buffer::ReadBuffer;
753
754 #[test]
755 fn test_value_null() {
756 let v = Value::Null;
757 assert!(v.is_null());
758 assert!(v.as_str().is_none());
759 assert!(v.as_i64().is_none());
760 }
761
762 #[test]
763 fn test_value_string() {
764 let v = Value::String("hello".to_string());
765 assert!(!v.is_null());
766 assert_eq!(v.as_str(), Some("hello"));
767 assert_eq!(format!("{}", v), "hello");
768 }
769
770 #[test]
771 fn test_value_integer() {
772 let v = Value::Integer(42);
773 assert_eq!(v.as_i64(), Some(42));
774 assert_eq!(v.as_f64(), Some(42.0));
775 assert_eq!(format!("{}", v), "42");
776 }
777
778 #[test]
779 fn test_value_float() {
780 let v = Value::Float(3.14);
781 assert!((v.as_f64().unwrap() - 3.14).abs() < 0.001);
782 assert_eq!(v.as_i64(), Some(3));
783 }
784
785 #[test]
786 fn test_value_boolean() {
787 let v_true = Value::Boolean(true);
788 let v_false = Value::Boolean(false);
789 assert_eq!(v_true.as_bool(), Some(true));
790 assert_eq!(v_false.as_bool(), Some(false));
791 }
792
793 #[test]
794 fn test_row_creation() {
795 let values = vec![
796 Value::String("test".to_string()),
797 Value::Integer(123),
798 Value::Null,
799 ];
800 let row = Row::new(values);
801
802 assert_eq!(row.len(), 3);
803 assert!(!row.is_empty());
804 assert_eq!(row.get_string(0), Some("test"));
805 assert_eq!(row.get_i64(1), Some(123));
806 assert!(row.is_null(2));
807 }
808
809 #[test]
810 fn test_row_with_names() {
811 let values = vec![Value::Integer(1), Value::String("hello".to_string())];
812 let names = vec!["ID".to_string(), "NAME".to_string()];
813 let row = Row::with_names(values, names);
814
815 assert_eq!(row.get_by_name("ID").and_then(Value::as_i64), Some(1));
816 assert_eq!(row.get_by_name("name").and_then(Value::as_str), Some("hello"));
817 assert!(row.get_by_name("nonexistent").is_none());
818 }
819
820 #[test]
821 fn test_row_index() {
822 let values = vec![Value::Integer(42)];
823 let row = Row::new(values);
824 assert!(matches!(&row[0], Value::Integer(42)));
825 }
826
827 fn make_column(name: &str, oracle_type: OracleType, buffer_size: u32) -> ColumnInfo {
828 ColumnInfo {
829 name: name.to_string(),
830 oracle_type,
831 data_size: buffer_size,
832 buffer_size,
833 precision: 0,
834 scale: 0,
835 nullable: true,
836 csfrm: 0,
837 type_schema: None,
838 type_name: None,
839 domain_schema: None,
840 domain_name: None,
841 is_json: false,
842 is_oson: false,
843 vector_dimensions: None,
844 vector_format: None,
845 element_type: None,
846 }
847 }
848
849 #[test]
850 fn test_decode_null_value() {
851 let columns = vec![make_column("TEST", OracleType::Varchar, 100)];
852
853 let decoder = RowDataDecoder::new(&columns);
854 let data = vec![255u8]; let mut buf = ReadBuffer::new(bytes::Bytes::from(data));
856
857 let value = decoder.decode_column_value(&mut buf, &columns[0]).unwrap();
858 assert!(value.is_null());
859 }
860
861 #[test]
862 fn test_decode_string_value() {
863 let columns = vec![make_column("TEST", OracleType::Varchar, 100)];
864
865 let decoder = RowDataDecoder::new(&columns);
866 let data = vec![5u8, b'h', b'e', b'l', b'l', b'o'];
867 let mut buf = ReadBuffer::new(bytes::Bytes::from(data));
868
869 let value = decoder.decode_column_value(&mut buf, &columns[0]).unwrap();
870 assert_eq!(value.as_str(), Some("hello"));
871 }
872
873 #[test]
874 fn test_decode_integer_value() {
875 let columns = vec![make_column("NUM", OracleType::Number, 22)];
876
877 let decoder = RowDataDecoder::new(&columns);
878 let data = vec![3u8, 0xc2, 0x02, 0x18];
880 let mut buf = ReadBuffer::new(bytes::Bytes::from(data));
881
882 let value = decoder.decode_column_value(&mut buf, &columns[0]).unwrap();
883 assert_eq!(value.as_i64(), Some(123));
884 }
885
886 #[test]
887 fn test_bit_vector_duplicate_detection() {
888 let columns = vec![
889 make_column("COL1", OracleType::Number, 22),
890 make_column("COL2", OracleType::Number, 22),
891 ];
892
893 let mut decoder = RowDataDecoder::new(&columns);
894
895 decoder.set_bit_vector(vec![0b00000001]);
897
898 assert!(!decoder.is_duplicate(0)); assert!(decoder.is_duplicate(1)); }
901
902 #[test]
903 fn test_value_display() {
904 assert_eq!(format!("{}", Value::Null), "NULL");
905 assert_eq!(format!("{}", Value::Integer(42)), "42");
906 assert_eq!(format!("{}", Value::Float(3.14)), "3.14");
907 assert_eq!(format!("{}", Value::String("test".into())), "test");
908 assert_eq!(format!("{}", Value::Boolean(true)), "true");
909 assert_eq!(format!("{}", Value::Bytes(vec![1, 2, 3])), "<3 bytes>");
910 }
911
912 #[test]
913 fn test_decode_binary_float() {
914 let columns = vec![make_column("FLOAT_COL", OracleType::BinaryFloat, 4)];
915
916 let decoder = RowDataDecoder::new(&columns);
917
918 let encoded = crate::types::encode_binary_float(1.0f32);
920 let mut data = vec![4u8]; data.extend_from_slice(&encoded);
922
923 let mut buf = ReadBuffer::new(bytes::Bytes::from(data));
924 let value = decoder.decode_column_value(&mut buf, &columns[0]).unwrap();
925
926 assert!((value.as_f64().unwrap() - 1.0).abs() < 0.0001);
927 }
928
929 #[test]
930 fn test_decode_binary_double() {
931 let columns = vec![make_column("DOUBLE_COL", OracleType::BinaryDouble, 8)];
932
933 let decoder = RowDataDecoder::new(&columns);
934
935 let encoded = crate::types::encode_binary_double(3.14159f64);
937 let mut data = vec![8u8]; data.extend_from_slice(&encoded);
939
940 let mut buf = ReadBuffer::new(bytes::Bytes::from(data));
941 let value = decoder.decode_column_value(&mut buf, &columns[0]).unwrap();
942
943 assert!((value.as_f64().unwrap() - 3.14159).abs() < 0.00001);
944 }
945}