@@ -599,45 +599,51 @@ def _rebuild(self, array, array_type, path, rhs, **kw):
599599 array = f"coalesce({ array } , CAST(ARRAY[] AS { array_sql_type } ))"
600600 bound = path [0 ]
601601 if isinstance (bound , Slice ):
602- if not isinstance (bound .step , Null ) and not (
603- isinstance (bound .step , BindParameter )
604- and bound .step .unique
605- and type (bound .step .value ) is int
606- and bound .step .value == 1
607- ):
608- raise exc .CompileError ("Athena ARRAY slices support only step=None or step=1" )
609- start = "1" if isinstance (bound .start , Null ) else self ._index_sql (bound .start , ** kw )
610- stop = (
611- f"cardinality({ array } )"
612- if isinstance (bound .stop , Null )
613- else self ._index_sql (bound .stop , ** kw )
614- )
615- prefix = f"slice({ array } , 1, least({ start } - 1, cardinality({ array } )))"
616- element_type = compiler ._complex_dml_type (_ArrayTypeInspector .item_type (array_type ))
617- padding = (
618- f"repeat(CAST(NULL AS { element_type } ), "
619- f"CAST(greatest({ start } - 1 - cardinality({ array } ), 0) AS INTEGER))"
620- )
621- tail_start = f"greatest({ start } , { stop } + 1)"
622- suffix = (
623- f"slice({ array } , { tail_start } , "
624- f"greatest(cardinality({ array } ) - { tail_start } + 1, 0))"
625- )
626- return compiler ._array_slice_step (
627- f"concat({ prefix } , { padding } , { rhs } , { suffix } )" , bound .step , array_type , ** kw
628- )
602+ return self ._rebuild_slice (array , array_type , bound , rhs , ** kw )
603+ return self ._rebuild_element (array , array_type , bound , path [1 :], rhs , ** kw )
604+
605+ def _prefix_and_padding (self , array , start , array_type ):
606+ prefix = f"slice({ array } , 1, least({ start } - 1, cardinality({ array } )))"
607+ element_type = self .compiler ._complex_dml_type (_ArrayTypeInspector .item_type (array_type ))
608+ padding = (
609+ f"repeat(CAST(NULL AS { element_type } ), "
610+ f"CAST(greatest({ start } - 1 - cardinality({ array } ), 0) AS INTEGER))"
611+ )
612+ return prefix , padding
613+
614+ def _rebuild_slice (self , array , array_type , bound , rhs , ** kw ):
615+ if not isinstance (bound .step , Null ) and not (
616+ isinstance (bound .step , BindParameter )
617+ and bound .step .unique
618+ and type (bound .step .value ) is int
619+ and bound .step .value == 1
620+ ):
621+ raise exc .CompileError ("Athena ARRAY slices support only step=None or step=1" )
622+ start = "1" if isinstance (bound .start , Null ) else self ._index_sql (bound .start , ** kw )
623+ stop = (
624+ f"cardinality({ array } )"
625+ if isinstance (bound .stop , Null )
626+ else self ._index_sql (bound .stop , ** kw )
627+ )
628+ prefix , padding = self ._prefix_and_padding (array , start , array_type )
629+ tail_start = f"greatest({ start } , { stop } + 1)"
630+ suffix = (
631+ f"slice({ array } , { tail_start } , greatest(cardinality({ array } ) - { tail_start } + 1, 0))"
632+ )
633+ return self .compiler ._array_slice_step (
634+ f"concat({ prefix } , { padding } , { rhs } , { suffix } )" , bound .step , array_type , ** kw
635+ )
636+
637+ def _rebuild_element (self , array , array_type , bound , remaining_path , rhs , ** kw ):
629638 index = self ._index_sql (bound , ** kw )
630639 previous = f"element_at({ array } , { index } )"
631640 replacement = (
632- self ._rebuild (previous , _ArrayTypeInspector .item_type (array_type ), path [1 :], rhs , ** kw )
633- if len (path ) > 1
641+ self ._rebuild (
642+ previous , _ArrayTypeInspector .item_type (array_type ), remaining_path , rhs , ** kw
643+ )
644+ if remaining_path
634645 else rhs
635646 )
636- prefix = f"slice({ array } , 1, least({ index } - 1, cardinality({ array } )))"
637- element_type = compiler ._complex_dml_type (_ArrayTypeInspector .item_type (array_type ))
638- padding = (
639- f"repeat(CAST(NULL AS { element_type } ), "
640- f"CAST(greatest({ index } - 1 - cardinality({ array } ), 0) AS INTEGER))"
641- )
647+ prefix , padding = self ._prefix_and_padding (array , index , array_type )
642648 suffix = f"slice({ array } , { index } + 1, greatest(cardinality({ array } ) - { index } , 0))"
643649 return f"concat({ prefix } , { padding } , ARRAY[{ replacement } ], { suffix } )"
0 commit comments