@@ -271,9 +271,9 @@ def build_data(data, type)
271271 if value . nil?
272272 validity_buffer_builder ||= SparseBitmapBuilder . new
273273 validity_buffer_builder . unset ( i )
274- buffer . append_as_bytes ( [ 0 ] . pack ( pack_template ) )
274+ buffer . append_as_bytes ( pack_value ( nil , pack_template ) )
275275 else
276- buffer . append_as_bytes ( [ value ] . pack ( pack_template ) )
276+ buffer . append_as_bytes ( pack_value ( value , pack_template ) )
277277 end
278278 n += 1
279279 end
@@ -282,6 +282,11 @@ def build_data(data, type)
282282 buffer . freeze
283283 return n , validity_buffer , IO ::Buffer . for ( buffer )
284284 end
285+
286+ def pack_value ( value , template )
287+ value = 0 if value . nil?
288+ [ value ] . pack ( template )
289+ end
285290 end
286291
287292 class BooleanArray < PrimitiveArray
@@ -491,29 +496,80 @@ class IntervalArray < TemporalArray
491496 end
492497
493498 class YearMonthIntervalArray < IntervalArray
499+ class << self
500+ def type
501+ YearMonthIntervalType . singleton
502+ end
503+ end
494504 end
495505
496506 class DayTimeIntervalArray < IntervalArray
507+ class << self
508+ def type
509+ DayTimeIntervalType . singleton
510+ end
511+ end
512+
497513 def to_a
498514 return [ ] if empty?
499515
500516 offset = element_size * @offset
501517 values = @values_buffer .
502518 each ( @type . buffer_type , offset , @size * 2 ) .
503519 each_slice ( 2 ) .
504- collect do |( _ , day ) , ( _ , time ) |
505- [ day , time ]
520+ collect do |( _ , day ) , ( _ , millisecond ) |
521+ [ day , millisecond ]
506522 end
507523 apply_validity ( values )
508524 end
509525
526+ def each ( &block )
527+ return to_enum ( __method__ ) { @size } unless block_given?
528+
529+ each_value = Enumerator . new ( @size ) do |yielder |
530+ offset = element_size * @offset
531+ @values_buffer .
532+ each ( @type . buffer_type , offset , @size * 2 ) .
533+ each_slice ( 2 ) do |( _ , day ) , ( _ , millisecond ) |
534+ yielder << [ day , millisecond ]
535+ end
536+ end
537+ if @validity_buffer . nil?
538+ each_value . each ( &block )
539+ else
540+ validity_bitmap . zip ( each_value ) do |is_valid , value |
541+ if is_valid
542+ yield ( value )
543+ else
544+ yield ( nil )
545+ end
546+ end
547+ end
548+ end
549+
510550 private
511551 def element_size
512552 super * 2
513553 end
554+
555+ def pack_value ( value , template )
556+ if value . nil?
557+ [ 0 , 0 ] . pack ( template )
558+ elsif value . is_a? ( Hash )
559+ [ value [ :day ] , value [ :millisecond ] ] . pack ( template )
560+ else
561+ value . pack ( template )
562+ end
563+ end
514564 end
515565
516566 class MonthDayNanoIntervalArray < IntervalArray
567+ class << self
568+ def type
569+ MonthDayNanoIntervalType . singleton
570+ end
571+ end
572+
517573 def to_a
518574 return [ ] if empty?
519575
@@ -527,10 +583,45 @@ def to_a
527583 apply_validity ( values )
528584 end
529585
586+ def each ( &block )
587+ return to_enum ( __method__ ) { @size } unless block_given?
588+
589+ each_value = Enumerator . new ( @size ) do |yielder |
590+ buffer_types = @type . buffer_types
591+ value_size = IO ::Buffer . size_of ( buffer_types )
592+ base_offset = value_size * @offset
593+ @size . times do |i |
594+ offset = base_offset + value_size * i
595+ yielder << @values_buffer . get_values ( buffer_types , offset )
596+ end
597+ end
598+ if @validity_buffer . nil?
599+ each_value . each ( &block )
600+ else
601+ validity_bitmap . zip ( each_value ) do |is_valid , value |
602+ if is_valid
603+ yield ( value )
604+ else
605+ yield ( nil )
606+ end
607+ end
608+ end
609+ end
610+
530611 private
531612 def element_size
532613 IO ::Buffer . size_of ( @type . buffer_types )
533614 end
615+
616+ def pack_value ( value , template )
617+ if value . nil?
618+ [ 0 , 0 , 0 ] . pack ( template )
619+ elsif value . is_a? ( Hash )
620+ [ value [ :month ] , value [ :day ] , value [ :nanosecond ] ] . pack ( template )
621+ else
622+ value . pack ( template )
623+ end
624+ end
534625 end
535626
536627 class DurationArray < TemporalArray
0 commit comments