duckdb 1.10505.0

Ergonomic wrapper for DuckDB
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
use pretty_assertions::assert_eq;

use crate::{
    Connection,
    types::{Decimal, FromSql, OrderedMap, TimeUnit, Type, Value, ValueRef},
};

const POINT_EMPTY_WKB: &[u8] = &[
    0x01, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xF8, 0x7F, 0, 0, 0, 0, 0, 0, 0xF8, 0x7F,
];

const GEOMETRY_COLLECTION_WKB: &[u8] = &[
    0x01, 0x07, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x01, 0x02, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x02,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x18, 0x40, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x01, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F,
    0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
    0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x01, 0x07, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];

#[test]
fn test_all_types() -> crate::Result<()> {
    test_with_database(&Connection::open_in_memory()?)
}

#[test]
fn test_large_arrow_types() -> crate::Result<()> {
    let cfg = crate::Config::default().with("arrow_large_buffer_size", "true")?;
    let database = Connection::open_in_memory_with_flags(cfg)?;

    test_with_database(&database)
}

fn test_with_database(database: &Connection) -> crate::Result<()> {
    let excluded = ["time_tz", "time_ns", "bignum"];

    let mut binding = database.prepare(&format!(
        "SELECT * EXCLUDE ({}) FROM test_all_types()",
        excluded
            .iter()
            .map(|s| format!("'{s}'"))
            .collect::<Vec<String>>()
            .join(",")
    ))?;
    let mut rows = binding.query([])?;

    let mut idx = -1;
    while let Some(row) = rows.next()? {
        idx += 1;
        for column in row.stmt.column_names() {
            let value = row.get_ref_unwrap(row.stmt.column_index(&column)?);
            if idx != 2 {
                assert_ne!(value.data_type(), Type::Null, "column {column} is null: {value:?}");
            }
            test_single(&mut idx, column, value);
        }
    }

    Ok(())
}

fn test_single(idx: &mut i32, column: String, value: ValueRef<'_>) {
    match column.as_str() {
        "bool" => match idx {
            0 => assert_eq!(value, ValueRef::Boolean(false)),
            1 => assert_eq!(value, ValueRef::Boolean(true)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "tinyint" => match idx {
            0 => assert_eq!(value, ValueRef::TinyInt(-128)),
            1 => assert_eq!(value, ValueRef::TinyInt(127)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "smallint" => match idx {
            0 => assert_eq!(value, ValueRef::SmallInt(-32768)),
            1 => assert_eq!(value, ValueRef::SmallInt(32767)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "int" => match idx {
            0 => assert_eq!(value, ValueRef::Int(-2147483648)),
            1 => assert_eq!(value, ValueRef::Int(2147483647)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "bigint" => match idx {
            0 => assert_eq!(value, ValueRef::BigInt(-9223372036854775808)),
            1 => assert_eq!(value, ValueRef::BigInt(9223372036854775807)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "hugeint" => match idx {
            0 => assert_eq!(value, ValueRef::HugeInt(-170141183460469231731687303715884105728)),
            1 => assert_eq!(value, ValueRef::HugeInt(170141183460469231731687303715884105727)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "utinyint" => match idx {
            0 => assert_eq!(value, ValueRef::UTinyInt(0)),
            1 => assert_eq!(value, ValueRef::UTinyInt(255)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "usmallint" => match idx {
            0 => assert_eq!(value, ValueRef::USmallInt(0)),
            1 => assert_eq!(value, ValueRef::USmallInt(65535)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "uint" => match idx {
            0 => assert_eq!(value, ValueRef::UInt(0)),
            1 => assert_eq!(value, ValueRef::UInt(4294967295)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "ubigint" => match idx {
            0 => assert_eq!(value, ValueRef::UBigInt(0)),
            1 => assert_eq!(value, ValueRef::UBigInt(18446744073709551615)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "uhugeint" => match idx {
            0 => assert_eq!(value, ValueRef::UHugeInt(0)),
            1 => assert_eq!(value, ValueRef::UHugeInt(u128::MAX)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "float" => match idx {
            0 => assert_eq!(value, ValueRef::Float(-3.4028235e38)),
            1 => assert_eq!(value, ValueRef::Float(3.4028235e38)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "double" => match idx {
            0 => assert_eq!(value, ValueRef::Double(-1.7976931348623157e308)),
            1 => assert_eq!(value, ValueRef::Double(1.7976931348623157e308)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "decimal" => match idx {
            0 => assert_eq!(value, ValueRef::Decimal(Decimal::new(18, 0, 0).unwrap())),
            1 => assert_eq!(value, ValueRef::Decimal(Decimal::new(18, 0, 1).unwrap())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "date" => match idx {
            0 => assert_eq!(value, ValueRef::Date32(-2147483646)),
            1 => assert_eq!(value, ValueRef::Date32(2147483646)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "time" => match idx {
            0 => assert_eq!(value, ValueRef::Time64(TimeUnit::Microsecond, 0)),
            1 => assert_eq!(value, ValueRef::Time64(TimeUnit::Microsecond, 86400000000)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "timestamp" => match idx {
            0 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Microsecond, -9223372022400000000)),
            1 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Microsecond, 9223372036854775806)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "timestamp_s" => match idx {
            0 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Second, -9223372022400)),
            1 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Second, 9223372036854)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "timestamp_ms" => match idx {
            0 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Millisecond, -9223372022400000)),
            1 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Millisecond, 9223372036854775)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "timestamp_ns" => match idx {
            0 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Nanosecond, -9223286400000000000)),
            1 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Nanosecond, 9223372036854775806)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "timestamp_tz" => match idx {
            0 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Microsecond, -9223372022400000000)),
            1 => assert_eq!(value, ValueRef::Timestamp(TimeUnit::Microsecond, 9223372036854775806)),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "dec_4_1" => match idx {
            0 => assert_eq!(value, ValueRef::Decimal(Decimal::new(4, 1, -9999).unwrap())),
            1 => assert_eq!(value, ValueRef::Decimal(Decimal::new(4, 1, 9999).unwrap())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "dec_9_4" => match idx {
            0 => assert_eq!(value, ValueRef::Decimal(Decimal::new(9, 4, -999999999).unwrap())),
            1 => assert_eq!(value, ValueRef::Decimal(Decimal::new(9, 4, 999999999).unwrap())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "dec_18_6" => match idx {
            0 => assert_eq!(
                value,
                ValueRef::Decimal(Decimal::new(18, 6, -999999999999999999).unwrap())
            ),
            1 => assert_eq!(
                value,
                ValueRef::Decimal(Decimal::new(18, 6, 999999999999999999).unwrap())
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "dec38_10" => match idx {
            0 => assert_eq!(
                value,
                ValueRef::Decimal(Decimal::new(38, 10, -99_999_999_999_999_999_999_999_999_999_999_999_999).unwrap())
            ),
            1 => assert_eq!(
                value,
                ValueRef::Decimal(Decimal::new(38, 10, 99_999_999_999_999_999_999_999_999_999_999_999_999).unwrap())
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "uuid" => match idx {
            0 => assert_eq!(value, ValueRef::Text("00000000-0000-0000-0000-000000000000".as_bytes())),
            1 => assert_eq!(value, ValueRef::Text("ffffffff-ffff-ffff-ffff-ffffffffffff".as_bytes())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "varchar" => match idx {
            0 => assert_eq!(value, ValueRef::Text("🦆🦆🦆🦆🦆🦆".as_bytes())),
            1 => assert_eq!(value, ValueRef::Text("goo\0se".as_bytes())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "blob" => match idx {
            0 => assert_eq!(
                value,
                ValueRef::Blob(&[
                    116, 104, 105, 115, 105, 115, 97, 108, 111, 110, 103, 98, 108, 111, 98, 0, 119, 105, 116, 104, 110,
                    117, 108, 108, 98, 121, 116, 101, 115
                ])
            ),
            1 => assert_eq!(value, ValueRef::Blob(&[0, 0, 0, 97])),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "geometry" => match idx {
            0 => {
                assert_eq!(value.data_type(), Type::Geometry);
                assert_eq!(value.as_geometry_wkb().unwrap(), POINT_EMPTY_WKB);
                assert_eq!(value.as_blob().unwrap(), POINT_EMPTY_WKB);
                assert_eq!(Vec::<u8>::column_result(value).unwrap(), POINT_EMPTY_WKB);
                match value.to_owned() {
                    Value::Geometry(wkb) => assert_eq!(wkb, POINT_EMPTY_WKB),
                    other => panic!("expected Geometry value, got {other:?}"),
                }
            }
            1 => {
                assert_eq!(value.data_type(), Type::Geometry);
                assert_eq!(value.as_geometry_wkb().unwrap(), GEOMETRY_COLLECTION_WKB);
                assert_eq!(value.as_blob().unwrap(), GEOMETRY_COLLECTION_WKB);
                assert_eq!(Vec::<u8>::column_result(value).unwrap(), GEOMETRY_COLLECTION_WKB);
                match value.to_owned() {
                    Value::Geometry(wkb) => assert_eq!(wkb, GEOMETRY_COLLECTION_WKB),
                    other => panic!("expected Geometry value, got {other:?}"),
                }
            }
            _ => assert_eq!(value, ValueRef::Null),
        },
        "int_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Int(42),
                    Value::Int(999),
                    Value::Null,
                    Value::Null,
                    Value::Int(-42),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "double_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => {
                let value = value.to_owned();

                if let Value::List(values) = value {
                    assert_eq!(values.len(), 6);
                    assert_eq!(values[0], Value::Double(42.0));
                    assert!(unwrap(&values[1]).is_nan());
                    let val = unwrap(&values[2]);
                    assert!(val.is_infinite() && val.is_sign_positive());
                    let val = unwrap(&values[3]);
                    assert!(val.is_infinite() && val.is_sign_negative());
                    assert_eq!(values[4], Value::Null);
                    assert_eq!(values[5], Value::Double(-42.0));
                }
            }
            _ => assert_eq!(value, ValueRef::Null),
        },
        "float_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![Value::Float(1.0), Value::Float(2.0)])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "date_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Date32(0),
                    Value::Date32(2147483647),
                    Value::Date32(-2147483647),
                    Value::Null,
                    Value::Date32(19124),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "timestamp_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Timestamp(TimeUnit::Microsecond, 0,),
                    Value::Timestamp(TimeUnit::Microsecond, 9223372036854775807,),
                    Value::Timestamp(TimeUnit::Microsecond, -9223372036854775807,),
                    Value::Null,
                    Value::Timestamp(TimeUnit::Microsecond, 1652372625000000,),
                ],)
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "timestamptz_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Timestamp(TimeUnit::Microsecond, 0,),
                    Value::Timestamp(TimeUnit::Microsecond, 9223372036854775807,),
                    Value::Timestamp(TimeUnit::Microsecond, -9223372036854775807,),
                    Value::Null,
                    Value::Timestamp(TimeUnit::Microsecond, 1652397825000000,),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "varchar_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Text("🦆🦆🦆🦆🦆🦆".to_string()),
                    Value::Text("goose".to_string()),
                    Value::Null,
                    Value::Text("".to_string()),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "nested_int_array" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => {
                assert_eq!(
                    value.to_owned(),
                    Value::List(vec![
                        Value::List(vec![],),
                        Value::List(vec![
                            Value::Int(42,),
                            Value::Int(999,),
                            Value::Null,
                            Value::Null,
                            Value::Int(-42,),
                        ],),
                        Value::Null,
                        Value::List(vec![],),
                        Value::List(vec![
                            Value::Int(42,),
                            Value::Int(999,),
                            Value::Null,
                            Value::Null,
                            Value::Int(-42,),
                        ],),
                    ],)
                )
            }
            _ => assert_eq!(value, ValueRef::Null),
        },
        "struct" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Struct(OrderedMap::from(vec![
                    ("a".to_string(), Value::Null),
                    ("b".to_string(), Value::Null),
                ]))
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Struct(OrderedMap::from(vec![
                    ("a".to_string(), Value::Int(42)),
                    ("b".to_string(), Value::Text("🦆🦆🦆🦆🦆🦆".to_string())),
                ]))
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "struct_of_arrays" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Struct(OrderedMap::from(vec![
                    ("a".to_string(), Value::Null),
                    ("b".to_string(), Value::Null),
                ]))
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Struct(OrderedMap::from(vec![
                    (
                        "a".to_string(),
                        Value::List(vec![
                            Value::Int(42),
                            Value::Int(999),
                            Value::Null,
                            Value::Null,
                            Value::Int(-42)
                        ])
                    ),
                    (
                        "b".to_string(),
                        Value::List(vec![
                            Value::Text("🦆🦆🦆🦆🦆🦆".to_string()),
                            Value::Text("goose".to_string()),
                            Value::Null,
                            Value::Text("".to_string()),
                        ]),
                    )
                ]))
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "array_of_structs" => match idx {
            0 => assert_eq!(value.to_owned(), Value::List(vec![])),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Null),
                        ("b".to_string(), Value::Null)
                    ])),
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Int(42)),
                        ("b".to_string(), Value::Text("🦆🦆🦆🦆🦆🦆".to_string()))
                    ])),
                    Value::Null
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "map" => match idx {
            0 => assert_eq!(value.to_owned(), Value::Map(OrderedMap::from(vec![]))),
            1 => assert_eq!(
                value.to_owned(),
                Value::Map(OrderedMap::from(vec![
                    (Value::Text("key1".to_string()), Value::Text("🦆🦆🦆🦆🦆🦆".to_string())),
                    (Value::Text("key2".to_string()), Value::Text("goose".to_string())),
                ]))
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "fixed_int_array" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)])
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![Value::Int(4), Value::Int(5), Value::Int(6)])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "fixed_varchar_array" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Text("a".to_string()),
                    Value::Null,
                    Value::Text("c".to_string())
                ])
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Text("d".to_string()),
                    Value::Text("e".to_string()),
                    Value::Text("f".to_string())
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "fixed_nested_int_array" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)]),
                    Value::Null,
                    Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)])
                ])
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Array(vec![Value::Int(4), Value::Int(5), Value::Int(6)]),
                    Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)]),
                    Value::Array(vec![Value::Int(4), Value::Int(5), Value::Int(6)]),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "fixed_nested_varchar_array" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Array(vec![
                        Value::Text("a".to_string()),
                        Value::Null,
                        Value::Text("c".to_string())
                    ]),
                    Value::Null,
                    Value::Array(vec![
                        Value::Text("a".to_string()),
                        Value::Null,
                        Value::Text("c".to_string())
                    ])
                ])
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Array(vec![
                        Value::Text("d".to_string()),
                        Value::Text("e".to_string()),
                        Value::Text("f".to_string())
                    ]),
                    Value::Array(vec![
                        Value::Text("a".to_string()),
                        Value::Null,
                        Value::Text("c".to_string())
                    ]),
                    Value::Array(vec![
                        Value::Text("d".to_string()),
                        Value::Text("e".to_string()),
                        Value::Text("f".to_string())
                    ]),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "fixed_struct_array" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Null),
                        ("b".to_string(), Value::Null)
                    ])),
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Int(42)),
                        ("b".to_string(), Value::Text("🦆🦆🦆🦆🦆🦆".to_string()))
                    ])),
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Null),
                        ("b".to_string(), Value::Null)
                    ])),
                ])
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Int(42)),
                        ("b".to_string(), Value::Text("🦆🦆🦆🦆🦆🦆".to_string()))
                    ])),
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Null),
                        ("b".to_string(), Value::Null)
                    ])),
                    Value::Struct(OrderedMap::from(vec![
                        ("a".to_string(), Value::Int(42)),
                        ("b".to_string(), Value::Text("🦆🦆🦆🦆🦆🦆".to_string()))
                    ])),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "struct_of_fixed_array" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Struct(OrderedMap::from(vec![
                    (
                        "a".to_string(),
                        Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)])
                    ),
                    (
                        "b".to_string(),
                        Value::Array(vec![
                            Value::Text("a".to_string()),
                            Value::Null,
                            Value::Text("c".to_string())
                        ])
                    ),
                ]))
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Struct(OrderedMap::from(vec![
                    (
                        "a".to_string(),
                        Value::Array(vec![Value::Int(4), Value::Int(5), Value::Int(6)]),
                    ),
                    (
                        "b".to_string(),
                        Value::Array(vec![
                            Value::Text("d".to_string()),
                            Value::Text("e".to_string()),
                            Value::Text("f".to_string())
                        ]),
                    )
                ]))
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "fixed_array_of_int_list" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::List(vec![]),
                    Value::List(vec![
                        Value::Int(42),
                        Value::Int(999),
                        Value::Null,
                        Value::Null,
                        Value::Int(-42),
                    ]),
                    Value::List(vec![]),
                ])
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::Array(vec![
                    Value::List(vec![
                        Value::Int(42),
                        Value::Int(999),
                        Value::Null,
                        Value::Null,
                        Value::Int(-42),
                    ]),
                    Value::List(vec![]),
                    Value::List(vec![
                        Value::Int(42),
                        Value::Int(999),
                        Value::Null,
                        Value::Null,
                        Value::Int(-42),
                    ]),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "list_of_fixed_int_array" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)]),
                    Value::Array(vec![Value::Int(4), Value::Int(5), Value::Int(6)]),
                    Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)]),
                ])
            ),
            1 => assert_eq!(
                value.to_owned(),
                Value::List(vec![
                    Value::Array(vec![Value::Int(4), Value::Int(5), Value::Int(6)]),
                    Value::Array(vec![Value::Null, Value::Int(2), Value::Int(3)]),
                    Value::Array(vec![Value::Int(4), Value::Int(5), Value::Int(6)]),
                ])
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "bit" => match idx {
            0 => assert_eq!(value, ValueRef::Blob(&[1, 145, 46, 42, 215]),),
            1 => assert_eq!(value, ValueRef::Blob(&[3, 245])),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "interval" => match idx {
            0 => assert_eq!(
                value,
                ValueRef::Interval {
                    months: 0,
                    days: 0,
                    nanos: 0
                }
            ),
            1 => assert_eq!(
                value,
                ValueRef::Interval {
                    months: 999,
                    days: 999,
                    nanos: 999999999000
                }
            ),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "small_enum" => match idx {
            0 => assert_eq!(value.to_owned(), Value::Enum("DUCK_DUCK_ENUM".to_string())),
            1 => assert_eq!(value.to_owned(), Value::Enum("GOOSE".to_string())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "medium_enum" => match idx {
            0 => assert_eq!(value.to_owned(), Value::Enum("enum_0".to_string())),
            1 => assert_eq!(value.to_owned(), Value::Enum("enum_299".to_string())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "large_enum" => match idx {
            0 => assert_eq!(value.to_owned(), Value::Enum("enum_0".to_string())),
            1 => assert_eq!(value.to_owned(), Value::Enum("enum_69999".to_string())),
            _ => assert_eq!(value, ValueRef::Null),
        },
        "union" => match idx {
            0 => assert_eq!(
                value.to_owned(),
                Value::Union(Box::new(Value::Text("Frank".to_owned())))
            ),
            1 => assert_eq!(value.to_owned(), Value::Union(Box::new(Value::SmallInt(5)))),
            _ => assert_eq!(value.to_owned(), Value::Union(Box::new(Value::Null))),
        },
        _ => todo!("{column:?}"),
    }
}

fn unwrap(value: &Value) -> f64 {
    if let Value::Double(val) = value {
        *val
    } else {
        panic!();
    }
}