Repository: ibis-project/ibis

Issue:
SUPP: Raise exception on backends where rows_with_max_lookback can't be implemented
Follow up from https://github.com/ibis-project/ibis/pull/1825


Discussion:

Resolving patch:
diff --git a/ibis/impala/compiler.py b/ibis/impala/compiler.py
--- a/ibis/impala/compiler.py
+++ b/ibis/impala/compiler.py
@@ -334,6 +334,10 @@ def _window(translator, expr):
 def _format_window(translator, op, window):
     components = []
 
+    if window.max_lookback is not None:
+        raise NotImplementedError('Rows with max lookback is not implemented '
+                                  'for Impala-based backends.')
+
     if len(window._group_by) > 0:
         partition_args = [translator.translate(x) for x in window._group_by]
         components.append('PARTITION BY {}'.format(', '.join(partition_args)))
diff --git a/ibis/pandas/execution/window.py b/ibis/pandas/execution/window.py
--- a/ibis/pandas/execution/window.py
+++ b/ibis/pandas/execution/window.py
@@ -90,6 +90,10 @@ def execute_window_op(
         **kwargs,
     )
 
+    if window.max_lookback is not None:
+        raise NotImplementedError('Rows with max lookback is not implemented '
+                                  'for pandas backend.')
+
     following = window.following
     order_by = window._order_by
 
diff --git a/ibis/sql/alchemy.py b/ibis/sql/alchemy.py
--- a/ibis/sql/alchemy.py
+++ b/ibis/sql/alchemy.py
@@ -564,6 +564,10 @@ def _window(t, expr):
         arg = _cumulative_to_window(t, arg, window)
         return t.translate(arg)
 
+    if window.max_lookback is not None:
+        raise NotImplementedError('Rows with max lookback is not implemented '
+                                  'for SQLAlchemy-based backends.')
+
     # Some analytic functions need to have the expression of interest in
     # the ORDER BY part of the window clause
     if isinstance(window_op, _require_order_by) and not window._order_by:


Test patch:
diff --git a/ibis/impala/tests/test_window.py b/ibis/impala/tests/test_window.py
--- a/ibis/impala/tests/test_window.py
+++ b/ibis/impala/tests/test_window.py
@@ -107,13 +107,7 @@ def test_add_default_order_by(alltypes):
         (
             ibis.trailing_window(10),
             'rows between 10 preceding and current row',
-        ),
-        (
-            ibis.trailing_window(
-                rows_with_max_lookback(3, ibis.interval(days=3))
-            ),
-            'rows between 3 preceding and current row',
-        ),
+        )
     ],
 )
 def test_window_frame_specs(con, window, frame):
@@ -129,6 +123,15 @@ def test_window_frame_specs(con, window, frame):
     assert_sql_equal(expr, expected)
 
 
+def test_window_rows_with_max_lookback(con):
+    t = con.table('alltypes')
+    mlb = rows_with_max_lookback(3, ibis.interval(days=3))
+    w = ibis.trailing_window(mlb)
+    expr = t.a.sum().over(w)
+    with pytest.raises(NotImplementedError):
+        to_sql(expr)
+
+
 @pytest.mark.parametrize(
     ('cumulative', 'static'),
     [
diff --git a/ibis/pandas/execution/tests/test_window.py b/ibis/pandas/execution/tests/test_window.py
--- a/ibis/pandas/execution/tests/test_window.py
+++ b/ibis/pandas/execution/tests/test_window.py
@@ -302,21 +302,11 @@ def test_batting_rolling_with_mlb(batting, batting_df, sort_kind):
             ibis.trailing_window(rows_with_mlb, order_by=t.yearID)
         )
     )
-    result = expr.execute()
-
-    columns = ['G', 'yearID']
-    more_values = (
-        batting_df[columns]
-        .sort_values('yearID', kind=sort_kind)
-        .G.rolling(5, min_periods=1)
-        .sum()
-    )
-    expected = batting_df.assign(more_values=more_values)
-
-    tm.assert_frame_equal(result[expected.columns], expected)
+    with pytest.raises(NotImplementedError):
+        expr.execute()
 
+    rows_with_mlb = rows_with_max_lookback(5, 10)
     with pytest.raises(com.IbisInputError):
-        rows_with_mlb = rows_with_max_lookback(5, 10)
         batting.mutate(
             more_values=lambda t: t.G.sum().over(
                 ibis.trailing_window(rows_with_mlb, order_by=t.yearID)
diff --git a/ibis/sql/postgres/tests/test_functions.py b/ibis/sql/postgres/tests/test_functions.py
--- a/ibis/sql/postgres/tests/test_functions.py
+++ b/ibis/sql/postgres/tests/test_functions.py
@@ -15,6 +15,7 @@
 import ibis.expr.datatypes as dt
 import ibis.expr.types as ir
 from ibis import literal as L
+from ibis.expr.window import rows_with_max_lookback
 
 sa = pytest.importorskip('sqlalchemy')
 pytest.importorskip('psycopg2')
@@ -886,6 +887,16 @@ def test_rolling_window(alltypes, func, df):
     tm.assert_series_equal(result, expected)
 
 
+def test_rolling_window_with_mlb(alltypes):
+    t = alltypes
+    window = ibis.trailing_window(
+        rows_with_max_lookback(3, ibis.interval(days=5))
+    )
+    expr = t['double_col'].sum().over(window)
+    with pytest.raises(NotImplementedError):
+        expr.execute()
+
+
 @pytest.mark.parametrize('func', ['mean', 'sum', 'min', 'max'])
 def test_partitioned_window(alltypes, func, df):
     t = alltypes