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