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