Skip to content

Commit 8f3f237

Browse files
Separate ARRAY element and slice update rendering
1 parent e58f4e0 commit 8f3f237

1 file changed

Lines changed: 41 additions & 35 deletions

File tree

‎pyathena/sqlalchemy/array.py‎

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)