voltdb_client_rust/
encode.rs

1use std::fmt::Debug;
2use std::str::Utf8Error;
3use std::sync::PoisonError;
4
5use bigdecimal::BigDecimal;
6use bigdecimal::num_bigint::BigInt;
7use bytebuffer::ByteBuffer;
8use chrono::{DateTime, Utc};
9use quick_error::quick_error;
10
11use crate::Column;
12use crate::chrono::TimeZone;
13use crate::response::VoltResponseInfo;
14
15#[allow(dead_code)]
16pub const ARRAY_COLUMN: i8 = -99;
17pub const NULL_COLUMN: i8 = 1;
18pub const TINYINT_COLUMN: i8 = 3;
19pub const SHORT_COLUMN: i8 = 4;
20pub const INT_COLUMN: i8 = 5;
21pub const LONG_COLUMN: i8 = 6;
22pub const FLOAT_COLUMN: i8 = 8;
23pub const STRING_COLUMN: i8 = 9;
24pub const TIMESTAMP_COLUMN: i8 = 11;
25pub const TABLE: i8 = 21;
26pub const DECIMAL_COLUMN: i8 = 22;
27pub const VAR_BIN_COLUMN: i8 = 25; // varbinary (int)(bytes)
28
29pub const NULL_DECIMAL: [u8; 16] = [128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
30
31pub const NULL_BIT_VALUE: [u8; 1] = [128];
32pub const NULL_SHORT_VALUE: [u8; 2] = [128, 0];
33pub const NULL_INT_VALUE: [u8; 4] = [128, 0, 0, 0];
34pub const NULL_LONG_VALUE: [u8; 8] = [128, 0, 0, 0, 0, 0, 0, 0];
35pub const NULL_TIMESTAMP: [u8; 8] = [128, 0, 0, 0, 0, 0, 0, 0];
36
37pub const NULL_FLOAT_VALUE: [u8; 8] = [255, 239, 255, 255, 255, 255, 255, 255];
38pub const NULL_VARCHAR: [u8; 4] = [255, 255, 255, 255];
39
40quick_error! {
41#[derive(Debug)]
42pub enum VoltError {
43        Io(err: std::io::Error) {
44            from()
45            display("I/O error: {}", err)
46            source(err)
47        }
48
49        RecvError(err: std::sync::mpsc::RecvError){
50            from()
51            display("Recv error: {}", err)
52            source(err)
53        }
54
55        ExecuteFail ( info: VoltResponseInfo ){
56            display("volt execute failed: {:?}", info)
57        }
58        InvalidColumnType(tp: i8) {
59            display("InvalidColumnType {}", tp)
60        }
61
62        MessageTooLarge(tp: usize) {
63            display("MessageTooLarge {}", tp)
64        }
65
66        NoValue (descr : String) {
67            display("Error {}", descr)
68        }
69        Other(descr: String) {
70            display("Error {}", descr)
71        }
72        NegativeNumTables (num: i16) {
73             display("Error {}", num)
74        }
75
76         Utf8Error(err : Utf8Error){
77            from()
78            display("Utf8 error: {}", err)
79            source(err)
80        }
81
82        PoisonError (descr: String){
83              display("Error {}", descr)
84        }
85        BadReturnStatusOnTable (status: i8) {
86             display("Error {}", status)
87        }
88        AuthFailed {
89             display("Auth failed")
90        }
91        ConnectionNotAvailable {
92             display("Connection lost")
93        }
94        InvalidConfig {
95             display("Invalid Config")
96        }
97        Timeout {
98             display("Operation timeout")
99        }
100        ConnectionClosed {
101             display("Connection Closed")
102        }
103        /// Returned when a non-Option type encounters a NULL value.
104        /// Use Option<T> if the column may contain NULL values.
105        UnexpectedNull(column: String) {
106            display("Unexpected NULL value in column '{}'. Use Option<T> for nullable columns.", column)
107        }
108}}
109
110impl<T> From<PoisonError<T>> for VoltError {
111    fn from(p: PoisonError<T>) -> VoltError {
112        VoltError::PoisonError(p.to_string().to_owned())
113    }
114}
115
116pub trait ValuePrimary {}
117
118//pub trait
119pub trait Value: Debug + Send + Sync {
120    fn get_write_length(&self) -> i32;
121    fn marshal(&self, bytebuffer: &mut ByteBuffer);
122    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8);
123    fn to_value_string(&self) -> String;
124    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError>
125    where
126        Self: Sized;
127}
128
129trait WriteBool {
130    fn write_bool(&mut self, val: bool);
131}
132
133impl WriteBool for ByteBuffer {
134    fn write_bool(&mut self, val: bool) {
135        if val {
136            self.write_i8(1)
137        } else {
138            self.write_i8(0);
139        }
140    }
141}
142
143impl Value for bool {
144    fn get_write_length(&self) -> i32 {
145        2
146    }
147
148    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
149        bytebuffer.write_i8(TINYINT_COLUMN);
150        bytebuffer.write_bool(*self);
151    }
152
153    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
154        bytebuffer.write_bool(*self);
155    }
156
157    fn to_value_string(&self) -> String {
158        self.to_string()
159    }
160
161    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
162        if bs[0] == 0 {
163            return Ok(false);
164        }
165        Ok(true)
166    }
167}
168
169impl Value for BigDecimal {
170    fn get_write_length(&self) -> i32 {
171        17
172    }
173
174    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
175        bytebuffer.write_i8(DECIMAL_COLUMN);
176        self.marshal_in_table(bytebuffer, DECIMAL_COLUMN);
177    }
178
179    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
180        let (b, _) = self.clone().with_scale(12).into_bigint_and_exponent();
181        let bs = b.to_signed_bytes_be();
182        let pad = 16 - bs.len();
183        if pad > 0 {
184            let arr = vec![0; pad];
185            bytebuffer.write_bytes(&arr)
186        }
187        bytebuffer.write_bytes(&bs);
188    }
189
190    fn to_value_string(&self) -> String {
191        self.to_string()
192    }
193
194    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError>
195    where
196        Self: Sized,
197    {
198        if bs == NULL_DECIMAL {
199            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
200        }
201        let int = BigInt::from_signed_bytes_be(&bs);
202        let decimal = BigDecimal::new(int, 12);
203        Ok(decimal)
204    }
205}
206
207impl Value for i8 {
208    fn get_write_length(&self) -> i32 {
209        2
210    }
211
212    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
213        bytebuffer.write_i8(TINYINT_COLUMN);
214        bytebuffer.write_i8(*self);
215    }
216
217    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
218        bytebuffer.write_i8(*self);
219    }
220
221    fn to_value_string(&self) -> String {
222        self.to_string()
223    }
224
225    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
226        if bs == NULL_BIT_VALUE {
227            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
228        }
229        let mut buffer = ByteBuffer::from_bytes(&bs);
230        let value = buffer.read_i8()?;
231        Ok(value)
232    }
233}
234
235impl Value for u8 {
236    fn get_write_length(&self) -> i32 {
237        2
238    }
239
240    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
241        bytebuffer.write_i8(TINYINT_COLUMN);
242        bytebuffer.write_u8(*self);
243    }
244
245    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
246        bytebuffer.write_u8(*self);
247    }
248
249    fn to_value_string(&self) -> String {
250        self.to_string()
251    }
252
253    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
254        if bs == NULL_BIT_VALUE {
255            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
256        }
257        let mut buffer = ByteBuffer::from_bytes(&bs);
258        let value = buffer.read_u8()?;
259        Ok(value)
260    }
261}
262
263impl Value for i16 {
264    fn get_write_length(&self) -> i32 {
265        3
266    }
267
268    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
269        bytebuffer.write_i8(SHORT_COLUMN);
270        bytebuffer.write_i16(*self);
271    }
272
273    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
274        bytebuffer.write_i16(*self);
275    }
276
277    fn to_value_string(&self) -> String {
278        self.to_string()
279    }
280
281    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
282        if bs == NULL_SHORT_VALUE {
283            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
284        }
285        let mut buffer = ByteBuffer::from_bytes(&bs);
286        let value = buffer.read_i16()?;
287        Ok(value)
288    }
289}
290
291impl Value for u16 {
292    fn get_write_length(&self) -> i32 {
293        3
294    }
295
296    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
297        bytebuffer.write_i8(SHORT_COLUMN);
298        bytebuffer.write_u16(*self);
299    }
300
301    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
302        bytebuffer.write_u16(*self);
303    }
304
305    fn to_value_string(&self) -> String {
306        self.to_string()
307    }
308
309    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
310        if bs == NULL_SHORT_VALUE {
311            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
312        }
313        let mut buffer = ByteBuffer::from_bytes(&bs);
314        let value = buffer.read_u16()?;
315        Ok(value)
316    }
317}
318
319impl Value for i32 {
320    fn get_write_length(&self) -> i32 {
321        5
322    }
323
324    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
325        bytebuffer.write_i8(INT_COLUMN);
326        bytebuffer.write_i32(*self);
327    }
328
329    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
330        bytebuffer.write_i32(*self);
331    }
332
333    fn to_value_string(&self) -> String {
334        self.to_string()
335    }
336
337    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
338        if bs == NULL_INT_VALUE {
339            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
340        }
341        let mut buffer = ByteBuffer::from_bytes(&bs);
342        let value = buffer.read_i32()?;
343        Ok(value)
344    }
345}
346
347impl Value for u32 {
348    fn get_write_length(&self) -> i32 {
349        5
350    }
351
352    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
353        bytebuffer.write_i8(INT_COLUMN);
354        bytebuffer.write_u32(*self);
355    }
356
357    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
358        bytebuffer.write_u32(*self);
359    }
360
361    fn to_value_string(&self) -> String {
362        self.to_string()
363    }
364
365    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
366        if bs == NULL_INT_VALUE {
367            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
368        }
369        let mut buffer = ByteBuffer::from_bytes(&bs);
370        let value = buffer.read_u32()?;
371        Ok(value)
372    }
373}
374
375impl Value for i64 {
376    fn get_write_length(&self) -> i32 {
377        9
378    }
379
380    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
381        bytebuffer.write_i8(LONG_COLUMN);
382        bytebuffer.write_i64(*self);
383    }
384
385    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
386        bytebuffer.write_i64(*self);
387    }
388
389    fn to_value_string(&self) -> String {
390        self.to_string()
391    }
392
393    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
394        if bs == NULL_LONG_VALUE {
395            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
396        }
397        let mut buffer = ByteBuffer::from_bytes(&bs);
398        let value = buffer.read_i64()?;
399        Ok(value)
400    }
401}
402
403impl Value for u64 {
404    fn get_write_length(&self) -> i32 {
405        9
406    }
407
408    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
409        bytebuffer.write_i8(LONG_COLUMN);
410        bytebuffer.write_u64(*self);
411    }
412
413    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
414        bytebuffer.write_u64(*self);
415    }
416
417    fn to_value_string(&self) -> String {
418        self.to_string()
419    }
420
421    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
422        if bs == NULL_LONG_VALUE {
423            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
424        }
425        let mut buffer = ByteBuffer::from_bytes(&bs);
426        let value = buffer.read_u64()?;
427        Ok(value)
428    }
429}
430
431impl Value for f64 {
432    fn get_write_length(&self) -> i32 {
433        9
434    }
435
436    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
437        bytebuffer.write_i8(FLOAT_COLUMN);
438        bytebuffer.write_f64(*self);
439    }
440
441    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
442        bytebuffer.write_f64(*self);
443    }
444
445    fn to_value_string(&self) -> String {
446        self.to_string()
447    }
448
449    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
450        if bs == NULL_FLOAT_VALUE {
451            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
452        }
453        let mut buffer = ByteBuffer::from_bytes(&bs);
454        let value = buffer.read_f64()?;
455        Ok(value)
456    }
457}
458
459impl Value for String {
460    fn get_write_length(&self) -> i32 {
461        (5 + self.len()) as i32
462    }
463
464    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
465        bytebuffer.write_i8(STRING_COLUMN);
466        bytebuffer.write_string(self);
467    }
468
469    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
470        bytebuffer.write_string(self);
471    }
472
473    fn to_value_string(&self) -> String {
474        self.to_string()
475    }
476
477    fn from_bytes(bs: Vec<u8>, table_column: &Column) -> Result<Self, VoltError> {
478        match table_column.header_type {
479            STRING_COLUMN => {
480                if bs == NULL_VARCHAR {
481                    return Err(VoltError::UnexpectedNull(table_column.header_name.clone()));
482                }
483                let mut buffer = ByteBuffer::from_bytes(&bs);
484                Ok(buffer.read_string()?)
485            }
486            _ => {
487                let res = crate::table::VoltTable::get_value_by_idx_column(table_column, bs)?;
488                match res {
489                    Some(v) => Ok(v.to_value_string()),
490                    None => Err(VoltError::UnexpectedNull(table_column.header_name.clone())),
491                }
492            }
493        }
494    }
495}
496
497impl Value for &str {
498    fn get_write_length(&self) -> i32 {
499        (5 + self.len()) as i32
500    }
501
502    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
503        bytebuffer.write_i8(STRING_COLUMN);
504        // write length , then data
505        bytebuffer.write_string(self);
506    }
507
508    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
509        bytebuffer.write_string(self);
510    }
511
512    fn to_value_string(&self) -> String {
513        self.to_string()
514    }
515
516    fn from_bytes(_bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
517        todo!()
518    }
519}
520
521impl Value for Vec<u8> {
522    fn get_write_length(&self) -> i32 {
523        (5 + self.len()) as i32
524    }
525
526    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
527        bytebuffer.write_i8(VAR_BIN_COLUMN);
528        bytebuffer.write_u32(self.len() as u32);
529        bytebuffer.write_bytes(self);
530    }
531
532    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
533        bytebuffer.write_u32(self.len() as u32);
534        bytebuffer.write_bytes(self);
535    }
536
537    fn to_value_string(&self) -> String {
538        format!("{:?}", self)
539    }
540
541    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> {
542        if bs == NULL_VARCHAR {
543            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
544        }
545        let mut cp = bs.clone();
546        cp.drain(0..4);
547        Ok(cp)
548    }
549}
550
551impl Value for DateTime<Utc> {
552    fn get_write_length(&self) -> i32 {
553        9
554    }
555    fn marshal(&self, bytebuffer: &mut ByteBuffer) {
556        bytebuffer.write_i8(TIMESTAMP_COLUMN);
557        bytebuffer.write_i64(self.timestamp_millis() * 1000);
558    }
559
560    fn marshal_in_table(&self, bytebuffer: &mut ByteBuffer, _column_type: i8) {
561        bytebuffer.write_i64(self.timestamp_millis() * 1000);
562    }
563
564    fn to_value_string(&self) -> String {
565        self.to_string()
566    }
567
568    fn from_bytes(bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError>
569    where
570        Self: Sized,
571    {
572        if bs == NULL_TIMESTAMP {
573            return Err(VoltError::UnexpectedNull(_column.header_name.clone()));
574        }
575        let mut buffer = ByteBuffer::from_bytes(&bs);
576        let time = buffer.read_i64()?;
577        Ok(Utc.timestamp_millis_opt(time / 1000).unwrap())
578    }
579}
580
581#[cfg(test)]
582mod tests {
583    use std::str::FromStr;
584
585    use bigdecimal::num_bigint::BigInt;
586    use chrono::TimeZone;
587
588    use crate::procedure_invocation::new_procedure_invocation;
589
590    use super::*;
591
592    #[test]
593    fn test_encoding_proc() {
594        let mut zero_vec: Vec<&dyn Value> = Vec::new();
595        zero_vec.push(&"select * from account limit 1;");
596
597        let mut proc = new_procedure_invocation(1, false, &zero_vec, "@AdHoc");
598        let bs = proc.bytes();
599        assert_eq!(
600            bs,
601            vec!(
602                0, 0, 0, 56, 0, 0, 0, 0, 6, 64, 65, 100, 72, 111, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
603                9, 0, 0, 0, 30, 115, 101, 108, 101, 99, 116, 32, 42, 32, 102, 114, 111, 109, 32,
604                97, 99, 99, 111, 117, 110, 116, 32, 108, 105, 109, 105, 116, 32, 49, 59
605            )
606        );
607    }
608
609    #[test]
610    fn test_time_stamp() {
611        let time = Utc.timestamp_millis_opt(1637323002445000 / 1000).unwrap();
612        println!("{}", time.timestamp_millis() * 1000);
613    }
614
615    #[test]
616    fn test_big_decimal() {
617        let bs: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 243, 16, 122, 64, 0];
618        let int = BigInt::from_signed_bytes_be(&*bs);
619        let decimal = BigDecimal::new(int, 12);
620        let (b, _) = decimal.into_bigint_and_exponent();
621        let b = b.to_signed_bytes_be();
622        println!("{:?}", b);
623
624        let decimal = BigDecimal::from_str("1.11").unwrap().with_scale(12);
625        println!("{:?}", decimal.into_bigint_and_exponent());
626    }
627
628    #[test]
629    fn test_big_test_bytes() {
630        let i = ByteBuffer::from_bytes(&NULL_BIT_VALUE).read_i8().unwrap();
631        assert_eq!(i, -128);
632        let i = ByteBuffer::from_bytes(&NULL_SHORT_VALUE)
633            .read_i16()
634            .unwrap();
635        assert_eq!(i, -32768);
636        let i = ByteBuffer::from_bytes(&NULL_INT_VALUE).read_i32().unwrap();
637        assert_eq!(i, -2147483648);
638        let i = ByteBuffer::from_bytes(&NULL_LONG_VALUE).read_i64().unwrap();
639        assert_eq!(i, -9223372036854775808);
640
641        let column = Column {
642            header_name: "".to_string(),
643            header_type: STRING_COLUMN,
644        };
645
646        let vec = NULL_BIT_VALUE.to_vec();
647        let op: Option<i8> = Option::from_bytes(vec, &column).unwrap();
648        assert_eq!(None, op);
649        let vec = NULL_BIT_VALUE.to_vec();
650        let op: Option<u8> = Option::from_bytes(vec, &column).unwrap();
651        assert_eq!(None, op);
652        let vec = NULL_SHORT_VALUE.to_vec();
653        let op: Option<i16> = Option::from_bytes(vec, &column).unwrap();
654        assert_eq!(None, op);
655        let vec = NULL_SHORT_VALUE.to_vec();
656        let op: Option<u16> = Option::from_bytes(vec, &column).unwrap();
657        assert_eq!(None, op);
658        let vec = NULL_INT_VALUE.to_vec();
659        let op: Option<i32> = Option::from_bytes(vec, &column).unwrap();
660        assert_eq!(None, op);
661        let vec = NULL_INT_VALUE.to_vec();
662        let op: Option<u32> = Option::from_bytes(vec, &column).unwrap();
663        assert_eq!(None, op);
664
665        let vec = NULL_LONG_VALUE.to_vec();
666        let op: Option<i64> = Option::from_bytes(vec, &column).unwrap();
667        assert_eq!(None, op);
668        let vec = NULL_LONG_VALUE.to_vec();
669        let op: Option<u64> = Option::from_bytes(vec, &column).unwrap();
670        assert_eq!(None, op);
671
672        let vec = NULL_VARCHAR.to_vec();
673        let op: Option<String> = Option::from_bytes(vec, &column).unwrap();
674        assert_eq!(None, op);
675
676        let vec = NULL_VARCHAR.to_vec();
677        let op: Option<Vec<u8>> = Option::from_bytes(vec, &column).unwrap();
678        assert_eq!(None, op);
679
680        let vec = NULL_FLOAT_VALUE.to_vec();
681        let op: Option<f64> = Option::from_bytes(vec, &column).unwrap();
682        assert_eq!(None, op);
683
684        let vec = NULL_DECIMAL.to_vec();
685        let op: Option<BigDecimal> = Option::from_bytes(vec, &column).unwrap();
686        assert_eq!(None, op);
687
688        let vec = NULL_TIMESTAMP.to_vec();
689        let op: Option<DateTime<Utc>> = Option::from_bytes(vec, &column).unwrap();
690        assert_eq!(None, op);
691    }
692
693    #[test]
694    fn test_error() {
695        let err = VoltError::NoValue("key is af".to_owned());
696        println!("{:?} {} ", err, err);
697    }
698
699    #[test]
700    fn test_non_option_null_returns_error_i8() {
701        let column = Column {
702            header_name: "test_col".to_string(),
703            header_type: TINYINT_COLUMN,
704        };
705        let result = i8::from_bytes(NULL_BIT_VALUE.to_vec(), &column);
706        assert!(result.is_err());
707        match result {
708            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "test_col"),
709            _ => panic!("Expected UnexpectedNull error"),
710        }
711    }
712
713    #[test]
714    fn test_non_option_null_returns_error_i16() {
715        let column = Column {
716            header_name: "short_col".to_string(),
717            header_type: SHORT_COLUMN,
718        };
719        let result = i16::from_bytes(NULL_SHORT_VALUE.to_vec(), &column);
720        assert!(result.is_err());
721        match result {
722            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "short_col"),
723            _ => panic!("Expected UnexpectedNull error"),
724        }
725    }
726
727    #[test]
728    fn test_non_option_null_returns_error_i32() {
729        let column = Column {
730            header_name: "int_col".to_string(),
731            header_type: INT_COLUMN,
732        };
733        let result = i32::from_bytes(NULL_INT_VALUE.to_vec(), &column);
734        assert!(result.is_err());
735        match result {
736            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "int_col"),
737            _ => panic!("Expected UnexpectedNull error"),
738        }
739    }
740
741    #[test]
742    fn test_non_option_null_returns_error_i64() {
743        let column = Column {
744            header_name: "long_col".to_string(),
745            header_type: LONG_COLUMN,
746        };
747        let result = i64::from_bytes(NULL_LONG_VALUE.to_vec(), &column);
748        assert!(result.is_err());
749        match result {
750            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "long_col"),
751            _ => panic!("Expected UnexpectedNull error"),
752        }
753    }
754
755    #[test]
756    fn test_non_option_null_returns_error_f64() {
757        let column = Column {
758            header_name: "float_col".to_string(),
759            header_type: FLOAT_COLUMN,
760        };
761        let result = f64::from_bytes(NULL_FLOAT_VALUE.to_vec(), &column);
762        assert!(result.is_err());
763        match result {
764            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "float_col"),
765            _ => panic!("Expected UnexpectedNull error"),
766        }
767    }
768
769    #[test]
770    fn test_non_option_null_returns_error_string() {
771        let column = Column {
772            header_name: "str_col".to_string(),
773            header_type: STRING_COLUMN,
774        };
775        let result = String::from_bytes(NULL_VARCHAR.to_vec(), &column);
776        assert!(result.is_err());
777        match result {
778            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "str_col"),
779            _ => panic!("Expected UnexpectedNull error"),
780        }
781    }
782
783    #[test]
784    fn test_non_option_null_returns_error_vec_u8() {
785        let column = Column {
786            header_name: "bin_col".to_string(),
787            header_type: VAR_BIN_COLUMN,
788        };
789        let result = Vec::<u8>::from_bytes(NULL_VARCHAR.to_vec(), &column);
790        assert!(result.is_err());
791        match result {
792            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "bin_col"),
793            _ => panic!("Expected UnexpectedNull error"),
794        }
795    }
796
797    #[test]
798    fn test_non_option_null_returns_error_datetime() {
799        let column = Column {
800            header_name: "time_col".to_string(),
801            header_type: TIMESTAMP_COLUMN,
802        };
803        let result = DateTime::<Utc>::from_bytes(NULL_TIMESTAMP.to_vec(), &column);
804        assert!(result.is_err());
805        match result {
806            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "time_col"),
807            _ => panic!("Expected UnexpectedNull error"),
808        }
809    }
810
811    #[test]
812    fn test_non_option_null_returns_error_decimal() {
813        let column = Column {
814            header_name: "dec_col".to_string(),
815            header_type: DECIMAL_COLUMN,
816        };
817        let result = BigDecimal::from_bytes(NULL_DECIMAL.to_vec(), &column);
818        assert!(result.is_err());
819        match result {
820            Err(VoltError::UnexpectedNull(col)) => assert_eq!(col, "dec_col"),
821            _ => panic!("Expected UnexpectedNull error"),
822        }
823    }
824
825    #[test]
826    fn test_non_null_values_work() {
827        let column = Column {
828            header_name: "col".to_string(),
829            header_type: INT_COLUMN,
830        };
831        // Non-NULL value (42 as big-endian i32)
832        let result = i32::from_bytes(vec![0, 0, 0, 42], &column);
833        assert!(result.is_ok());
834        assert_eq!(result.unwrap(), 42);
835    }
836
837    #[test]
838    fn test_unexpected_null_error_message() {
839        let err = VoltError::UnexpectedNull("my_column".to_string());
840        let msg = format!("{}", err);
841        assert!(msg.contains("my_column"));
842        assert!(msg.contains("Option<T>"));
843    }
844
845    // Marshal tests for basic types
846    #[test]
847    fn test_i8_marshal() {
848        let val: i8 = 42;
849        let mut buf = ByteBuffer::new();
850        val.marshal(&mut buf);
851        let bytes = buf.into_vec();
852        assert_eq!(bytes[0] as i8, TINYINT_COLUMN);
853        assert_eq!(bytes[1], 42);
854    }
855
856    #[test]
857    fn test_i8_get_write_length() {
858        let val: i8 = 1;
859        assert_eq!(val.get_write_length(), 2);
860    }
861
862    #[test]
863    fn test_u8_marshal() {
864        let val: u8 = 255;
865        let mut buf = ByteBuffer::new();
866        val.marshal(&mut buf);
867        let bytes = buf.into_vec();
868        assert_eq!(bytes[0] as i8, TINYINT_COLUMN);
869        assert_eq!(bytes[1], 255);
870    }
871
872    #[test]
873    fn test_i16_marshal() {
874        let val: i16 = 1000;
875        let mut buf = ByteBuffer::new();
876        val.marshal(&mut buf);
877        let bytes = buf.into_vec();
878        assert_eq!(bytes[0] as i8, SHORT_COLUMN);
879        assert_eq!(val.get_write_length(), 3);
880    }
881
882    #[test]
883    fn test_u16_marshal() {
884        let val: u16 = 65535;
885        let mut buf = ByteBuffer::new();
886        val.marshal(&mut buf);
887        assert_eq!(buf.into_vec()[0] as i8, SHORT_COLUMN);
888    }
889
890    #[test]
891    fn test_i32_marshal() {
892        let val: i32 = 123456;
893        let mut buf = ByteBuffer::new();
894        val.marshal(&mut buf);
895        let bytes = buf.into_vec();
896        assert_eq!(bytes[0] as i8, INT_COLUMN);
897        assert_eq!(val.get_write_length(), 5);
898    }
899
900    #[test]
901    fn test_u32_marshal() {
902        let val: u32 = 4294967295;
903        let mut buf = ByteBuffer::new();
904        val.marshal(&mut buf);
905        assert_eq!(buf.into_vec()[0] as i8, INT_COLUMN);
906    }
907
908    #[test]
909    fn test_i64_marshal() {
910        let val: i64 = 9876543210;
911        let mut buf = ByteBuffer::new();
912        val.marshal(&mut buf);
913        let bytes = buf.into_vec();
914        assert_eq!(bytes[0] as i8, LONG_COLUMN);
915        assert_eq!(val.get_write_length(), 9);
916    }
917
918    #[test]
919    fn test_u64_marshal() {
920        let val: u64 = 18446744073709551615;
921        let mut buf = ByteBuffer::new();
922        val.marshal(&mut buf);
923        assert_eq!(buf.into_vec()[0] as i8, LONG_COLUMN);
924    }
925
926    #[test]
927    fn test_f64_marshal() {
928        let val: f64 = 3.14159;
929        let mut buf = ByteBuffer::new();
930        val.marshal(&mut buf);
931        let bytes = buf.into_vec();
932        assert_eq!(bytes[0] as i8, FLOAT_COLUMN);
933        assert_eq!(val.get_write_length(), 9);
934    }
935
936    #[test]
937    fn test_bool_marshal_true() {
938        let val: bool = true;
939        let mut buf = ByteBuffer::new();
940        val.marshal(&mut buf);
941        let bytes = buf.into_vec();
942        assert_eq!(bytes[0] as i8, TINYINT_COLUMN);
943        assert_eq!(bytes[1], 1);
944    }
945
946    #[test]
947    fn test_bool_marshal_false() {
948        let val: bool = false;
949        let mut buf = ByteBuffer::new();
950        val.marshal(&mut buf);
951        let bytes = buf.into_vec();
952        assert_eq!(bytes[0] as i8, TINYINT_COLUMN);
953        assert_eq!(bytes[1], 0);
954    }
955
956    #[test]
957    fn test_string_marshal() {
958        let val: String = "hello".to_string();
959        let mut buf = ByteBuffer::new();
960        val.marshal(&mut buf);
961        let bytes = buf.into_vec();
962        assert_eq!(bytes[0] as i8, STRING_COLUMN);
963        assert_eq!(val.get_write_length(), 5 + 5); // header + "hello"
964    }
965
966    #[test]
967    fn test_str_marshal() {
968        let val: &str = "world";
969        let mut buf = ByteBuffer::new();
970        val.marshal(&mut buf);
971        let bytes = buf.into_vec();
972        assert_eq!(bytes[0] as i8, STRING_COLUMN);
973        assert_eq!(val.get_write_length(), 5 + 5); // header + "world"
974    }
975
976    #[test]
977    fn test_vec_u8_marshal() {
978        let val: Vec<u8> = vec![1, 2, 3, 4, 5];
979        let mut buf = ByteBuffer::new();
980        val.marshal(&mut buf);
981        let bytes = buf.into_vec();
982        assert_eq!(bytes[0] as i8, VAR_BIN_COLUMN);
983        assert_eq!(val.get_write_length(), 5 + 5); // header + 5 bytes
984    }
985
986    #[test]
987    fn test_datetime_marshal() {
988        let val = Utc.timestamp_millis_opt(1000000).unwrap();
989        let mut buf = ByteBuffer::new();
990        val.marshal(&mut buf);
991        let bytes = buf.into_vec();
992        assert_eq!(bytes[0] as i8, TIMESTAMP_COLUMN);
993        assert_eq!(val.get_write_length(), 9);
994    }
995
996    #[test]
997    fn test_bigdecimal_marshal() {
998        let val = BigDecimal::from_str("123.456789").unwrap();
999        let mut buf = ByteBuffer::new();
1000        val.marshal(&mut buf);
1001        let bytes = buf.into_vec();
1002        assert_eq!(bytes[0] as i8, DECIMAL_COLUMN);
1003        assert_eq!(val.get_write_length(), 17);
1004    }
1005
1006    // to_value_string tests
1007    #[test]
1008    fn test_i32_to_value_string() {
1009        let val: i32 = 42;
1010        assert_eq!(val.to_value_string(), "42");
1011    }
1012
1013    #[test]
1014    fn test_f64_to_value_string() {
1015        let val: f64 = 3.14;
1016        assert!(val.to_value_string().starts_with("3.14"));
1017    }
1018
1019    #[test]
1020    fn test_bool_to_value_string() {
1021        assert_eq!(true.to_value_string(), "true");
1022        assert_eq!(false.to_value_string(), "false");
1023    }
1024
1025    #[test]
1026    fn test_string_to_value_string() {
1027        let val = "hello".to_string();
1028        assert_eq!(val.to_value_string(), "hello");
1029    }
1030
1031    // Round-trip tests
1032    #[test]
1033    fn test_i32_roundtrip() {
1034        let col = Column {
1035            header_name: "test".to_string(),
1036            header_type: INT_COLUMN,
1037        };
1038        let original: i32 = 12345;
1039        let mut buf = ByteBuffer::new();
1040        original.marshal_in_table(&mut buf, INT_COLUMN);
1041        let bytes = buf.into_vec();
1042        let result = i32::from_bytes(bytes, &col).unwrap();
1043        assert_eq!(result, original);
1044    }
1045
1046    #[test]
1047    fn test_i64_roundtrip() {
1048        let col = Column {
1049            header_name: "test".to_string(),
1050            header_type: LONG_COLUMN,
1051        };
1052        let original: i64 = 9876543210;
1053        let mut buf = ByteBuffer::new();
1054        original.marshal_in_table(&mut buf, LONG_COLUMN);
1055        let bytes = buf.into_vec();
1056        let result = i64::from_bytes(bytes, &col).unwrap();
1057        assert_eq!(result, original);
1058    }
1059
1060    #[test]
1061    fn test_f64_roundtrip() {
1062        let col = Column {
1063            header_name: "test".to_string(),
1064            header_type: FLOAT_COLUMN,
1065        };
1066        let original: f64 = 3.14159;
1067        let mut buf = ByteBuffer::new();
1068        original.marshal_in_table(&mut buf, FLOAT_COLUMN);
1069        let bytes = buf.into_vec();
1070        let result = f64::from_bytes(bytes, &col).unwrap();
1071        assert!((result - original).abs() < 0.00001);
1072    }
1073}