@@ -10,61 +10,85 @@ use crate::amp::common::column_aliases;
1010
1111pub fn auto_block_number_decoder < ' a > (
1212 record_batch : & ' a RecordBatch ,
13- ) -> Result < Box < dyn Decoder < Option < BlockNumber > > + ' a > > {
14- let column_index = column_index ( record_batch, column_aliases:: BLOCK_NUMBER )
15- . context ( "failed to find block numbers column" ) ?;
13+ ) -> Result < ( & ' static str , Box < dyn Decoder < Option < BlockNumber > > + ' a > ) > {
14+ let ( & column_name, column_index) = find_column ( record_batch, column_aliases:: BLOCK_NUMBER )
15+ . with_context ( || {
16+ format ! (
17+ "failed to find block numbers column; expected one of: {}" ,
18+ column_aliases:: BLOCK_NUMBER . join( ", " )
19+ )
20+ } ) ?;
1621
1722 block_number_decoder ( record_batch, column_index)
23+ . map ( |decoder| ( column_name, decoder) )
24+ . with_context ( || format ! ( "column '{column_name}' is not valid" ) )
1825}
1926
2027pub fn block_number_decoder < ' a > (
2128 record_batch : & ' a RecordBatch ,
2229 column_index : usize ,
2330) -> Result < Box < dyn Decoder < Option < BlockNumber > > + ' a > > {
24- column_decoder :: < UInt64Array , BlockNumber > ( record_batch, column_index)
31+ column_decoder :: < UInt64Array , BlockNumber > ( record_batch, column_index, false )
2532}
2633
2734pub fn auto_block_hash_decoder < ' a > (
2835 record_batch : & ' a RecordBatch ,
29- ) -> Result < Box < dyn Decoder < Option < BlockHash > > + ' a > > {
30- let column_index = column_index ( record_batch, column_aliases:: BLOCK_HASH )
31- . context ( "failed to find block hashes column" ) ?;
36+ ) -> Result < ( & ' static str , Box < dyn Decoder < Option < BlockHash > > + ' a > ) > {
37+ let ( & column_name, column_index) = find_column ( record_batch, column_aliases:: BLOCK_HASH )
38+ . with_context ( || {
39+ format ! (
40+ "failed to find block hashes column; expected one of: {}" ,
41+ column_aliases:: BLOCK_HASH . join( ", " )
42+ )
43+ } ) ?;
3244
3345 block_hash_decoder ( record_batch, column_index)
46+ . map ( |decoder| ( column_name, decoder) )
47+ . with_context ( || format ! ( "column '{column_name}' is not valid" ) )
3448}
3549
3650pub fn block_hash_decoder < ' a > (
3751 record_batch : & ' a RecordBatch ,
3852 column_index : usize ,
3953) -> Result < Box < dyn Decoder < Option < BlockHash > > + ' a > > {
40- column_decoder :: < FixedSizeBinaryArray , BlockHash > ( record_batch, column_index)
54+ column_decoder :: < FixedSizeBinaryArray , BlockHash > ( record_batch, column_index, false )
4155}
4256
4357pub fn auto_block_timestamp_decoder < ' a > (
4458 record_batch : & ' a RecordBatch ,
45- ) -> Result < Box < dyn Decoder < Option < DateTime < Utc > > > + ' a > > {
46- let column_index = column_index ( record_batch, column_aliases:: BLOCK_TIMESTAMP )
47- . context ( "failed to find block timestamps column" ) ?;
59+ ) -> Result < ( & ' static str , Box < dyn Decoder < Option < DateTime < Utc > > > + ' a > ) > {
60+ let ( & column_name, column_index) = find_column ( record_batch, column_aliases:: BLOCK_TIMESTAMP )
61+ . with_context ( || {
62+ format ! (
63+ "failed to find block timestamps column; expected one of: {}" ,
64+ column_aliases:: BLOCK_TIMESTAMP . join( ", " )
65+ )
66+ } ) ?;
4867
4968 block_timestamp_decoder ( record_batch, column_index)
69+ . map ( |decoder| ( column_name, decoder) )
70+ . with_context ( || format ! ( "column '{column_name}' is not valid" ) )
5071}
5172
5273pub fn block_timestamp_decoder < ' a > (
5374 record_batch : & ' a RecordBatch ,
5475 column_index : usize ,
5576) -> Result < Box < dyn Decoder < Option < DateTime < Utc > > > + ' a > > {
56- column_decoder :: < TimestampNanosecondArray , DateTime < Utc > > ( record_batch, column_index)
77+ column_decoder :: < TimestampNanosecondArray , DateTime < Utc > > ( record_batch, column_index, false )
5778}
5879
59- pub fn column_index (
80+ pub fn find_column < T > (
6081 record_batch : & RecordBatch ,
61- column_names : impl IntoIterator < Item = impl AsRef < str > > ,
62- ) -> Option < usize > {
82+ column_names : impl IntoIterator < Item = T > ,
83+ ) -> Option < ( T , usize ) >
84+ where
85+ T : AsRef < str > ,
86+ {
6387 let schema_ref = record_batch. schema_ref ( ) ;
6488
6589 for column_name in column_names {
6690 if let Some ( ( column_index, _) ) = schema_ref. column_with_name ( column_name. as_ref ( ) ) {
67- return Some ( column_index) ;
91+ return Some ( ( column_name , column_index) ) ;
6892 }
6993 }
7094
@@ -74,16 +98,22 @@ pub fn column_index(
7498pub fn column_decoder < ' a , T : ' static , U > (
7599 record_batch : & ' a RecordBatch ,
76100 column_index : usize ,
101+ nullable : bool ,
77102) -> Result < Box < dyn Decoder < Option < U > > + ' a > >
78103where
79104 T : Array ,
80105 ArrayDecoder < ' a , T > : Decoder < Option < U > > ,
81106{
82107 if column_index >= record_batch. num_columns ( ) {
83- bail ! ( "column {column_index} does not exist" ) ;
108+ bail ! ( "column does not exist" ) ;
84109 }
85110
86111 let array = record_batch. column ( column_index) ;
112+
113+ if !nullable && array. is_nullable ( ) {
114+ bail ! ( "column must not have nullable values" ) ;
115+ }
116+
87117 let decoder = ArrayDecoder :: < T > :: new ( array) ?;
88118
89119 Ok ( Box :: new ( decoder) )
0 commit comments