1use std::collections::HashMap;
2use std::io::Read;
3
4use bigdecimal::BigDecimal;
5use bigdecimal::num_bigint::BigInt;
6use bytebuffer::ByteBuffer;
7use chrono::{DateTime, TimeZone, Utc};
8
9use crate::encode::{*};
10use crate::response::ResponseStatus::Success;
11use crate::response::VoltResponseInfo;
12
13const MIN_INT8: i8 = -1 << 7;
14
15#[derive(Debug, Clone, PartialEq)]
16pub struct Column {
17 pub header_name: String,
18 pub header_type: i8,
19}
20
21#[derive(Debug)]
22pub struct VoltTable {
23 info: VoltResponseInfo,
24 column_count: i16,
25 info_bytes: ByteBuffer,
26 column_info_bytes: ByteBuffer,
27 columns: Vec<Column>,
28 num_rows: i32,
29 rows: Vec<ByteBuffer>,
30 row_index: i32,
31 cn_to_ci: HashMap<String, i16>,
32 column_offsets: Vec<i32>,
33 header_size: i32,
34 total_size: i32,
35}
36
37impl Value for VoltTable {
38 fn get_write_length(&self) -> i32 {
39 return self.total_size + 5;
40 }
41
42 fn marshal(&self, bytebuffer: &mut ByteBuffer) {
43 bytebuffer.write_i8(TABLE);
44 bytebuffer.write_u32(self.total_size as u32);
45 bytebuffer.write_u32(self.header_size as u32);
46 bytebuffer.write_u8(128);
47 bytebuffer.write_bytes(&*self.column_info_bytes.to_bytes());
48 bytebuffer.write_u32(self.num_rows as u32);
49 self.rows.iter().for_each(|f| {
50 bytebuffer.write_u32(f.len() as u32);
51 bytebuffer.write_bytes(&*f.to_bytes());
52 });
53 println!("{}", bytebuffer.len())
54 }
55
56 fn marshal_in_table(&self, _bytebuffer: &mut ByteBuffer, _column_type: i8) {
57 }
59
60 fn to_value_string(&self) -> String {
61 return "table".to_owned();
62 }
63
64 fn from_bytes(_bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError> where Self: Sized {
65 todo!()
66 }
67}
68
69
70impl VoltTable {
71 pub fn new_table(types: Vec<i8>, header: Vec<String>) -> Self {
81 let mut columns = Vec::with_capacity(types.len());
82 for (i, tp) in types.iter().enumerate() {
83 columns.push(Column {
84 header_name: header.get(i).unwrap().clone(),
85 header_type: *tp,
86 })
87 }
88 return crate::table::VoltTable::new_voltdb_table(columns);
89 }
90
91 pub fn new_voltdb_table(columns: Vec<Column>) -> Self {
92 let mut column_info_bytes = ByteBuffer::new();
93
94 let column_count = columns.len() as i16;
95 column_info_bytes.write_i16(column_count);
96 columns.iter().for_each(|f| column_info_bytes.write_i8(f.header_type));
97 columns.iter().for_each(|f| column_info_bytes.write_string(f.header_name.as_str()));
98 let header_size = (1 + column_info_bytes.len()) as i32;
99 let total_size = header_size + 8;
100 return VoltTable {
102 info: Default::default(),
103 column_count,
104 info_bytes: Default::default(),
105 column_info_bytes,
106 columns,
107 num_rows: 0,
108 rows: vec![],
109 row_index: 0,
110 cn_to_ci: Default::default(),
111 column_offsets: vec![],
112 header_size,
113 total_size,
114 };
115 }
116
117 pub fn add_row(&mut self, row: Vec<&dyn Value>) -> Result<i16, VoltError> {
118 let mut bf: ByteBuffer = ByteBuffer::new();
119 self.columns.iter().enumerate().for_each(|(f, v)| {
120 let da = *row.get(f).unwrap();
121 da.marshal_in_table(&mut bf, v.header_type);
122 });
123 let len = bf.len();
124 self.rows.push(bf);
125 self.num_rows = self.num_rows + 1;
126 self.total_size = self.total_size + (len + 4) as i32;
127 return Ok(1);
128 }
129
130
131 pub fn get_column_index(&mut self, column: &str) -> Result<i16, VoltError> {
132 let idx = self.cn_to_ci.get(column.to_uppercase().as_str()).ok_or(VoltError::NoValue(column.to_owned()))?;
133 return Ok(*idx);
134 }
135
136 pub fn map_row<'a, T: From<&'a mut VoltTable>>(&'a mut self) -> T {
137 return T::from(self);
138 }
139 pub fn take<T: Value>(&mut self, column: i16) -> Result<T, VoltError> {
140 let bs = self.get_bytes_by_idx(column)?;
141 let column = self.get_column_by_index(column)?;
142 return T::from_bytes(bs, column);
143 }
144
145 pub fn fetch<T: Value>(&mut self, column: &str) -> Result<T, VoltError> {
146 let idx = self.get_column_index(column)?;
147 let bs = self.get_bytes_by_idx(idx)?;
148 let column = self.get_column_by_index(idx)?;
149 return T::from_bytes(bs, column);
150 }
151
152 pub fn debug_row(&mut self) -> String {
153 let x: Vec<String> = self.columns().into_iter().enumerate().map(|(idx, column)| {
154 return format!("{} {:?}", column.header_name, self.get_value_by_idx_type(idx as i16, column.header_type));
155 }).collect();
156 return x.join(" ");
157 }
158
159
160 pub fn has_error(&mut self) -> Option<VoltError> {
161 if self.info.get_status() == Success {
162 return Option::None;
163 }
164 return Option::Some(VoltError::ExecuteFail(self.info.clone()));
165 }
166
167 pub fn advance_row(&mut self) -> bool {
168 return self.advance_to_row(self.row_index + 1);
169 }
170
171 pub fn columns(&self) -> Vec<Column> {
172 self.columns.clone()
173 }
174
175 pub fn col_length(r: &mut ByteBuffer, offset: i32, col_type: i8) -> Result<i32, VoltError> {
176 match col_type {
177 crate::encode::ARRAY_COLUMN => {
178 return Err(VoltError::InvalidColumnType(col_type));
179 }
180 crate::encode::NULL_COLUMN => {
181 return Ok(0);
182 }
183 crate::encode::TINYINT_COLUMN => {
184 return Ok(1);
185 }
186 crate::encode::SHORT_COLUMN => {
188 return Ok(2);
189 }
190
191 crate::encode::INT_COLUMN => {
192 return Ok(4);
193 }
194 crate::encode::LONG_COLUMN => {
195 return Ok(8);
196 }
197 crate::encode::FLOAT_COLUMN => {
198 return Ok(8);
199 }
200 crate::encode::STRING_COLUMN => {
201 r.set_rpos(offset as usize);
202 let str_len = r.read_i32()?;
203 if str_len == -1 { return Ok(4);
205 }
206 return Ok(4 + str_len);
207 }
208 crate::encode::TIMESTAMP_COLUMN => {
209 return Ok(8);
210 }
211 crate::encode::DECIMAL_COLUMN => {
212 return Ok(16);
213 }
214 crate::encode::VAR_BIN_COLUMN => {
215 r.set_rpos(offset as usize);
216 let str_len = r.read_i32()?;
217 if str_len == -1 { return Ok(4);
219 }
220 return Ok(4 + str_len); }
222 _ => Err(VoltError::InvalidColumnType(col_type))
223 }
224 }
225
226 fn calc_offsets(&mut self) -> Result<(), VoltError> {
227 let mut offsets = Vec::with_capacity((self.column_count + 1) as usize);
228 let reader = self.rows.get_mut(self.row_index as usize).ok_or(VoltError::NoValue(self.row_index.to_string()))?;
229 offsets.push(0);
230 let mut offset = 0;
231 for i in 0..self.column_count {
232 let column = self.columns.get(i as usize).ok_or(VoltError::NoValue(i.to_string()))?;
233 let length = crate::table::VoltTable::col_length(reader, offset, column.header_type)?;
234 offset = offset + length;
235 offsets.push(offset);
236 }
237 reader.set_rpos(0);
238 self.column_offsets = offsets;
239 return Ok({});
240 }
241
242 pub fn get_value_by_column(&mut self, column: &str) -> Result<Option<Box<dyn Value>>, VoltError> {
243 let idx = self.get_column_index(column)?;
244 return Ok(self.get_value_by_idx(idx)?);
245 }
246
247 pub(crate) fn get_value_by_idx_column(column: &Column, bs: Vec<u8>) -> Result<Option<Box<dyn Value>>, VoltError> {
248 return match column.header_type {
249 crate::encode::TINYINT_COLUMN => {
250 let res = i8::from_bytes(bs, column)?;
251 match res {
252 i8::MIN => {
253 Ok(None)
254 }
255 _ => {
256 Ok(Some(Box::new(res)))
257 }
258 }
259 }
260 crate::encode::SHORT_COLUMN => {
261 let res = i16::from_bytes(bs, column)?;
262 match res {
263 i16::MIN => {
264 Ok(None)
265 }
266 _ => {
267 Ok(Some(Box::new(res)))
268 }
269 }
270 }
271 crate::encode::INT_COLUMN => {
272 let res = i32::from_bytes(bs, column)?;
273 match res {
274 i32::MIN => {
275 Ok(None)
276 }
277 _ => {
278 Ok(Some(Box::new(res)))
279 }
280 }
281 }
282
283 crate::encode::LONG_COLUMN => {
284 let res = i64::from_bytes(bs, column)?;
285 match res {
286 i64::MIN => {
287 Ok(None)
288 }
289 _ => {
290 Ok(Some(Box::new(res)))
291 }
292 }
293 }
294
295 crate::encode::FLOAT_COLUMN => {
296 if bs == NULL_FLOAT_VALUE {
297 return Ok(None);
298 }
299 let res = f64::from_bytes(bs, column)?;
300 return Ok(Some(Box::new(res)));
301 }
302
303 crate::encode::STRING_COLUMN => {
304 if bs.len() == 4 {
305 return Ok(None);
306 }
307 let res = String::from_bytes(bs, column)?;
308 return Ok(Some(Box::new(res)));
309 }
310
311 crate::encode::TIMESTAMP_COLUMN => {
312 if bs == NULL_TIMESTAMP {
313 return Ok(None);
314 }
315 let res = DateTime::from_bytes(bs, column)?;
316 return Ok(Some(Box::new(res)));
317 }
318 crate::encode::DECIMAL_COLUMN => {
319 if bs == NULL_DECIMAL {
320 return Ok(None);
321 }
322 let res = DateTime::from_bytes(bs, column)?;
323 return Ok(Some(Box::new(res)));
324 }
325 crate::encode::VAR_BIN_COLUMN => {
326 if bs.len() == 4 {
327 return Ok(None);
328 }
329 let res = Vec::from_bytes(bs, column)?;
330 return Ok(Some(Box::new(res)));
331 }
332 _ => {
333 let res = i16::from_bytes(bs, column)?;
334 Ok(Some(Box::new(res)))
337 }
340 };
341 }
342
343 pub(crate) fn get_value_by_idx_type(&mut self, column: i16, _tp: i8) -> Result<Option<Box<dyn Value>>, VoltError> {
344 let bs = self.get_bytes_by_idx(column)?;
345 let column = self.get_column_by_index(column)?;
346 return crate::table::VoltTable::get_value_by_idx_column(column, bs);
347 }
348
349
350 pub fn get_value_by_idx(&mut self, column: i16) -> Result<Option<Box<dyn Value>>, VoltError> {
351 let tp = self.get_column_type_by_idx(column)?;
352 return self.get_value_by_idx_type(column, tp);
353 }
354
355 pub fn get_bool_by_column(&mut self, column: &str) -> Result<Option<bool>, VoltError> {
356 let idx = self.get_column_index(column)?;
357 return Ok(self.get_bool_by_idx(idx)?);
358 }
359
360 pub fn get_bool_by_idx(&mut self, column: i16) -> Result<Option<bool>, VoltError> {
361 let bs = self.get_bytes_by_idx(column)?;
362 if bs == NULL_BIT_VALUE {
363 return Ok(Option::None);
364 }
365 if bs[0] == 0 {
366 return Ok(Some(false));
367 }
368 return Ok(Some(true));
369 }
370
371 pub fn get_bytes_op_by_column(&mut self, column: &str) -> Result<Option<Vec<u8>>, VoltError> {
372 let idx = self.get_column_index(column)?;
373 return Ok(self.get_bytes_op_by_idx(idx)?);
374 }
375
376 pub fn get_bytes_op_by_idx(&mut self, column: i16) -> Result<Option<Vec<u8>>, VoltError> {
377 let mut bs = self.get_bytes_by_idx(column)?;
378 if bs == NULL_VARCHAR {
379 return Ok(Option::None);
380 }
381 bs.drain(0..4);
382 return Ok(Option::Some(bs));
383 }
384
385 pub fn get_bytes_by_column(&mut self, column: &str) -> Result<Vec<u8>, VoltError> {
386 let idx = self.get_column_index(column)?;
387 return Ok(self.get_bytes_by_idx(idx)?);
388 }
389
390 pub fn get_decimal_by_column(&mut self, column: &str) -> Result<Option<BigDecimal>, VoltError> {
391 let idx = self.get_column_index(column)?;
392 return Ok(self.get_decimal_by_idx(idx)?);
393 }
394
395 pub fn get_decimal_by_idx(&mut self, column: i16) -> Result<Option<BigDecimal>, VoltError> {
396 let bs = self.get_bytes_by_idx(column)?;
397 if bs == NULL_DECIMAL {
398 return Ok(Option::None);
399 }
400 let int = BigInt::from_signed_bytes_be(&*bs);
401 let decimal = BigDecimal::new(int, 12);
402 return Ok(Some(decimal));
403 }
404
405 pub fn get_string_by_column(&mut self, column: &str) -> Result<Option<String>, VoltError> {
406 let idx = self.get_column_index(column)?;
407 return Ok(self.get_string_by_idx(idx)?);
408 }
409
410 pub fn get_column_by_index(&self, column: i16) -> Result<&Column, VoltError> {
411 let res = self.columns.get(column as usize);
412 return match res {
413 None => {
414 Err(VoltError::NoValue(self.row_index.to_string()))
415 }
416 Some(e) => {
417 Ok(e)
418 }
419 };
420 }
421
422 #[allow(mutable_borrow_reservation_conflict)]
423 pub fn get_string_by_idx(&mut self, column: i16) -> Result<Option<String>, VoltError> {
424 let table_column = self.get_column_by_index(column)?; return match table_column.header_type {
426 STRING_COLUMN => {
427 let bs = self.get_bytes_by_idx(column)?;
428 if bs == NULL_VARCHAR {
429 return Ok(Option::None);
430 }
431 let mut buffer = ByteBuffer::from_bytes(&bs);
432 Ok(Option::Some(buffer.read_string()?))
433 }
434 _ => {
435 let res = self.get_value_by_idx_type(column, table_column.header_type)?;
436 match res {
437 Some(v) => {
438 Ok(Option::Some(v.to_value_string()))
439 }
440 None => {
441 Ok(Option::None)
442 }
443 }
444 }
445 };
446 }
447
448 pub fn get_time_by_column(&mut self, column: &str) -> Result<Option<DateTime<Utc>>, VoltError> {
449 let idx = self.get_column_index(column)?;
450 return Ok(self.get_time_by_idx(idx)?);
451 }
452
453 pub fn get_time_by_idx(&mut self, column: i16) -> Result<Option<DateTime<Utc>>, VoltError> {
454 let bs = self.get_bytes_by_idx(column)?;
455 if bs == NULL_TIMESTAMP {
456 return Ok(Option::None);
457 }
458 let mut buffer = ByteBuffer::from_bytes(&bs);
459 let time = buffer.read_i64()?;
460 return Ok(Option::Some(Utc.timestamp_millis(time / 1000)));
461 }
462
463
464 pub fn get_bytes_by_idx(&mut self, column_index: i16) -> Result<Vec<u8>, VoltError> {
465 if self.column_offsets.len() == 0 {
466 self.calc_offsets()?;
467 }
468 let buffer = self.rows.get_mut(self.row_index as usize).ok_or(VoltError::NoValue(self.row_index.to_string()))?;
469 let start = self.column_offsets.get(column_index as usize).ok_or(VoltError::NoValue(column_index.to_string()))?;
470 let end = self.column_offsets.get(column_index as usize + 1).ok_or(VoltError::NoValue(column_index.to_string()))?;
471 buffer.set_rpos(*start as usize);
472 let rsize = (*end - *start) as usize;
473 Ok(buffer.read_bytes(rsize)?)
474 }
475
476 pub fn advance_to_row(&mut self, row_index: i32) -> bool {
477 if row_index >= self.num_rows {
478 return false;
479 }
480 self.column_offsets = vec![];
481 self.row_index = row_index;
482 return true;
483 }
484
485 fn get_column_type_by_idx(&self, column_idx: i16) -> Result<i8, VoltError> {
486 let v = self.columns.get(column_idx as usize);
487 if v.is_some() {
488 return Ok(v.unwrap().header_type);
489 }
490 return Err(VoltError::NoValue(column_idx.to_string()));
491 }
492}
493
494
495pub fn new_volt_table(bytebuffer: &mut ByteBuffer, info: VoltResponseInfo) -> Result<VoltTable, VoltError> {
496 if info.get_status() != Success {
497 return Ok(VoltTable {
498 info,
499 column_count: -1,
500 info_bytes: Default::default(),
501 column_info_bytes: Default::default(),
502 columns: vec![],
503 num_rows: -1,
504 rows: vec![],
505 row_index: -1,
506 cn_to_ci: Default::default(),
507 column_offsets: vec![],
508 header_size: 0,
509 total_size: 0,
510 });
511 }
512
513 let column_counts = decode_table_common(bytebuffer)?;
514 let mut column_types: Vec<i8> = Vec::with_capacity(column_counts as usize);
515 let mut column_info_bytes = ByteBuffer::new();
516 for _ in 0..column_counts {
517 let tp = bytebuffer.read_i8()?;
518 column_types.push(tp);
519 column_info_bytes.write_i8(tp);
520 }
521 let mut columns: Vec<Column> = Vec::with_capacity(column_counts as usize);
522 let mut cn_to_ci = HashMap::with_capacity(column_counts as usize);
523 for i in 0..column_counts {
524 let name = bytebuffer.read_string()?;
525 columns.push(Column {
526 header_name: name.clone(),
527 header_type: *(column_types.get(i as usize).unwrap()),
528 });
529 column_info_bytes.write_string(name.as_str());
530 cn_to_ci.insert(name, i);
531 }
532 let row_count = bytebuffer.read_i32()?;
533 let mut rows: Vec<ByteBuffer> = Vec::with_capacity(column_counts as usize);
534 for _ in 0..row_count {
535 let row_len = bytebuffer.read_i32()?;
536 let mut build = vec![0; row_len as usize];
537 bytebuffer.read_exact(&mut build)?;
538 let row = ByteBuffer::from_bytes(&*build);
539 rows.push(row);
540 }
541 return Ok(VoltTable {
542 info,
543 column_count: column_counts,
544 info_bytes: Default::default(),
545 column_info_bytes,
546 columns,
547 num_rows: row_count,
548 rows,
549 row_index: -1,
550 cn_to_ci,
551 column_offsets: vec![],
552 header_size: 0,
553 total_size: 0,
554 });
555}
556
557fn decode_table_common(bytebuffer: &mut ByteBuffer) -> Result<i16, VoltError> {
558 let _ttl_length = bytebuffer.read_i32();
559 let _meta_length = bytebuffer.read_i32();
560 let status_code = bytebuffer.read_i8()?;
561 if status_code != 0 && status_code != MIN_INT8 {
562 return Err(VoltError::BadReturnStatusOnTable(status_code));
564 }
565 return Ok(bytebuffer.read_i16()?);
566}
567
568
569#[cfg(test)]
570mod tests {
571 use crate::encode::{DECIMAL_COLUMN, FLOAT_COLUMN, INT_COLUMN, LONG_COLUMN, SHORT_COLUMN, STRING_COLUMN, TIMESTAMP_COLUMN, TINYINT_COLUMN, VAR_BIN_COLUMN};
572 use crate::volt_param;
573
574 use super::*;
575
576 fn template(tps: Vec<&str>, none: &str) {
577 for tp in tps {
578 let shader = r#"
579 pub fn get_${type}_by_column (&mut self, column: &str) -> Result<Option<${type}>, VoltError> {
580 let idx = self.get_column_index(column)?;
581 return Ok(self.get_${type}_by_idx>](idx)?);
582 }
583
584 pub fn get_${type}_by_idx (&mut self, column: i16) -> Result<Option<${type}>, VoltError> {
585 let bs = self.get_bytes_by_idx(column)?;
586 if bs == ${none} {
587 return Ok(Option::None);
588 }
589 let mut buffer = ByteBuffer::from_bytes(&bs);
590 let value = buffer.read_${type}()?;
591 return Ok(Some(value));
592 }
593"#;
594 println!("{}", shader.replace("${type}", tp).replace("${none}", none));
595 }
596 }
597
598 #[test]
599 fn test_encode_table() -> Result<(), VoltError> {
600 let bs = vec! {21, 0, 0, 0, 86, 0, 0, 0, 49, 128, 0, 4, 6, 6, 3, 6, 0, 0, 0, 2, 73, 68, 0, 0, 0, 7, 86, 69, 82, 83, 73, 79, 78, 0, 0, 0, 7, 68, 69, 76, 69, 84, 69, 68, 0, 0, 0, 10, 67, 82, 69, 65, 84, 69, 68, 95, 66, 89, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1};
601 let header = vec!["ID", "VERSION", "DELETED", "CREATED_BY"];
602 let tp = vec![LONG_COLUMN, LONG_COLUMN, TINYINT_COLUMN, LONG_COLUMN];
603 let header: Vec<String> = header.iter().map(|f| f.to_string()).collect::<Vec<String>>();
604 let mut x = VoltTable::new_table(tp, header);
605 let data = volt_param! {1 as i64, 1 as i64, false, 1 as i64 };
606 x.add_row(data)?;
607 let mut bf = ByteBuffer::new();
608 x.marshal(&mut bf);
609 assert_eq!(bs, bf.to_bytes());
610 Ok({})
611 }
612
613 #[test]
614 fn test_table() {
615 let bs = vec! {0 as u8, 1, 128, 0, 0, 0, 3, 0, 1, 0, 0, 0, 133, 0, 0, 0, 66, 128, 0, 9, 3, 4, 5, 6, 8, 22, 9, 25, 11, 0, 0, 0, 2, 84, 49, 0, 0, 0, 2, 84, 50, 0, 0, 0, 2, 84, 51, 0, 0, 0, 2, 84, 52, 0, 0, 0, 2, 84, 53, 0, 0, 0, 2, 84, 54, 0, 0, 0, 2, 84, 55, 0, 0, 0, 2, 84, 56, 0, 0, 0, 2, 84, 57, 0, 0, 0, 1, 0, 0, 0, 55, 128, 128, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 255, 239, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, 0, 0, 0};
616 let mut b = ByteBuffer::from_bytes(&bs);
617 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
618 let mut table = new_volt_table(&mut b, info).unwrap();
619 table.advance_row();
620
621 let header = table.columns();
622 assert_eq!(header.len(), 9);
623 assert_eq!(*header.get(0).unwrap(), Column {
624 header_name: "T1".to_owned(),
625 header_type: TINYINT_COLUMN,
626 });
627 assert_eq!(*header.get(1).unwrap(), Column {
628 header_name: "T2".to_owned(),
629 header_type: SHORT_COLUMN,
630 });
631 assert_eq!(*header.get(2).unwrap(), Column {
632 header_name: "T3".to_owned(),
633 header_type: INT_COLUMN,
634 });
635 assert_eq!(*header.get(3).unwrap(), Column {
636 header_name: "T4".to_owned(),
637 header_type: LONG_COLUMN,
638 });
639 assert_eq!(*header.get(4).unwrap(), Column {
640 header_name: "T5".to_owned(),
641 header_type: FLOAT_COLUMN,
642 });
643 assert_eq!(*header.get(5).unwrap(), Column {
644 header_name: "T6".to_owned(),
645 header_type: DECIMAL_COLUMN,
646 });
647 assert_eq!(*header.get(6).unwrap(), Column {
648 header_name: "T7".to_owned(),
649 header_type: STRING_COLUMN,
650 });
651 assert_eq!(*header.get(7).unwrap(), Column {
652 header_name: "T8".to_owned(),
653 header_type: VAR_BIN_COLUMN,
654 });
655 assert_eq!(*header.get(8).unwrap(), Column {
656 header_name: "T9".to_owned(),
657 header_type: TIMESTAMP_COLUMN,
658 });
659
660
661 let i1 = table.get_bool_by_idx(0).unwrap();
662 let i2 = table.get_i16_by_idx(1).unwrap();
663 let i3 = table.get_i32_by_idx(2).unwrap();
664 let i4 = table.get_i64_by_idx(3).unwrap();
665 let i5 = table.get_f64_by_idx(4).unwrap();
666 let i6 = table.get_decimal_by_idx(5).unwrap();
667 let i7 = table.get_string_by_idx(6).unwrap();
668 let i8 = table.get_bytes_op_by_idx(7).unwrap();
669 let i9 = table.get_time_by_idx(8).unwrap();
670
671 assert_eq!(i1, None);
672 assert_eq!(i2, None);
673 assert_eq!(i3, None);
674 assert_eq!(i4, None);
675 assert_eq!(i5, None);
676 assert_eq!(i6, None);
677 assert_eq!(i7, None);
678 assert_eq!(i8, None);
679 assert_eq!(i9, None);
680 let offsets = vec![0, 1, 3, 7, 15, 23, 39, 43, 47, 55];
681 assert_eq!(offsets, table.column_offsets);
682 }
683
684 #[test]
685 fn test_big_decimal() {
686 template(vec!("i8", "u8"), "NULL_BYTE_VALUE");
687 template(vec!("i16", "u16"), "NULL_SHORT_VALUE");
688 template(vec!("i32", "u32"), "NULL_INT_VALUE");
689 template(vec!("i64", "u64"), "NULL_LONG_VALUE");
690 template(vec!("f32", "f64"), "NULL_FLOAT_VALUE");
691 }
692}
693