diff --git a/ibis/backends/bigquery/compiler.py b/ibis/backends/bigquery/compiler.py index da0be2d3d9e8f..a359b42048891 100644 --- a/ibis/backends/bigquery/compiler.py +++ b/ibis/backends/bigquery/compiler.py @@ -18,8 +18,6 @@ exclude_unsupported_window_frame_from_ops, exclude_unsupported_window_frame_from_rank, exclude_unsupported_window_frame_from_row_number, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_sample_as_filter, ) from ibis.common.temporal import DateUnit, IntervalUnit, TimestampUnit, TimeUnit @@ -33,8 +31,6 @@ class BigQueryCompiler(SQLGlotCompiler): udf_type_mapper = BigQueryUDFType rewrites = ( rewrite_sample_as_filter, - rewrite_first_to_first_value, - rewrite_last_to_last_value, exclude_unsupported_window_frame_from_ops, exclude_unsupported_window_frame_from_row_number, exclude_unsupported_window_frame_from_rank, diff --git a/ibis/backends/flink/compiler.py b/ibis/backends/flink/compiler.py index c9e9191857d45..5bed84e647c80 100644 --- a/ibis/backends/flink/compiler.py +++ b/ibis/backends/flink/compiler.py @@ -15,8 +15,6 @@ exclude_unsupported_window_frame_from_ops, exclude_unsupported_window_frame_from_rank, exclude_unsupported_window_frame_from_row_number, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_sample_as_filter, ) @@ -30,8 +28,6 @@ class FlinkCompiler(SQLGlotCompiler): exclude_unsupported_window_frame_from_row_number, exclude_unsupported_window_frame_from_ops, exclude_unsupported_window_frame_from_rank, - rewrite_first_to_first_value, - rewrite_last_to_last_value, *SQLGlotCompiler.rewrites, ) diff --git a/ibis/backends/impala/compiler.py b/ibis/backends/impala/compiler.py index 53052fdf5bfdb..bf4b1cb4d67c5 100644 --- a/ibis/backends/impala/compiler.py +++ b/ibis/backends/impala/compiler.py @@ -12,8 +12,6 @@ from ibis.backends.sql.dialects import Impala from ibis.backends.sql.rewrites import ( rewrite_empty_order_by_window, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_sample_as_filter, ) @@ -25,8 +23,6 @@ class ImpalaCompiler(SQLGlotCompiler): type_mapper = ImpalaType rewrites = ( rewrite_sample_as_filter, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_empty_order_by_window, *SQLGlotCompiler.rewrites, ) diff --git a/ibis/backends/mssql/compiler.py b/ibis/backends/mssql/compiler.py index 5ff0a3e2bbc8f..dd53736a4d23f 100644 --- a/ibis/backends/mssql/compiler.py +++ b/ibis/backends/mssql/compiler.py @@ -24,8 +24,6 @@ exclude_unsupported_window_frame_from_row_number, p, replace, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_sample_as_filter, ) from ibis.common.deferred import var @@ -66,8 +64,6 @@ class MSSQLCompiler(SQLGlotCompiler): type_mapper = MSSQLType rewrites = ( rewrite_sample_as_filter, - rewrite_first_to_first_value, - rewrite_last_to_last_value, exclude_unsupported_window_frame_from_ops, exclude_unsupported_window_frame_from_row_number, rewrite_rows_range_order_by_window, diff --git a/ibis/backends/mysql/compiler.py b/ibis/backends/mysql/compiler.py index a26df1405a58a..e5b0d02833b24 100644 --- a/ibis/backends/mysql/compiler.py +++ b/ibis/backends/mysql/compiler.py @@ -18,8 +18,6 @@ exclude_unsupported_window_frame_from_rank, exclude_unsupported_window_frame_from_row_number, rewrite_empty_order_by_window, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_sample_as_filter, ) from ibis.common.patterns import replace @@ -53,8 +51,6 @@ class MySQLCompiler(SQLGlotCompiler): rewrites = ( rewrite_limit, rewrite_sample_as_filter, - rewrite_first_to_first_value, - rewrite_last_to_last_value, exclude_unsupported_window_frame_from_ops, exclude_unsupported_window_frame_from_rank, exclude_unsupported_window_frame_from_row_number, diff --git a/ibis/backends/oracle/compiler.py b/ibis/backends/oracle/compiler.py index e496f6b92728c..663778b75bf59 100644 --- a/ibis/backends/oracle/compiler.py +++ b/ibis/backends/oracle/compiler.py @@ -18,8 +18,6 @@ replace_log2, replace_log10, rewrite_empty_order_by_window, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_sample_as_filter, ) @@ -33,8 +31,6 @@ class OracleCompiler(SQLGlotCompiler): rewrites = ( exclude_unsupported_window_frame_from_row_number, exclude_unsupported_window_frame_from_ops, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_empty_order_by_window, rewrite_sample_as_filter, replace_log2, diff --git a/ibis/backends/snowflake/compiler.py b/ibis/backends/snowflake/compiler.py index 814a86d50d855..c0c1bc18e21c5 100644 --- a/ibis/backends/snowflake/compiler.py +++ b/ibis/backends/snowflake/compiler.py @@ -20,8 +20,6 @@ replace_log2, replace_log10, rewrite_empty_order_by_window, - rewrite_first_to_first_value, - rewrite_last_to_last_value, ) @@ -39,8 +37,6 @@ class SnowflakeCompiler(SQLGlotCompiler): rewrites = ( exclude_unsupported_window_frame_from_row_number, exclude_unsupported_window_frame_from_ops, - rewrite_first_to_first_value, - rewrite_last_to_last_value, rewrite_empty_order_by_window, replace_log2, replace_log10, diff --git a/ibis/backends/sql/rewrites.py b/ibis/backends/sql/rewrites.py index 7adbec86b0a25..58c3908c26a84 100644 --- a/ibis/backends/sql/rewrites.py +++ b/ibis/backends/sql/rewrites.py @@ -122,10 +122,23 @@ def sort_to_select(_, **kwargs): @replace(p.WindowFunction) def window_function_to_window(_, **kwargs): - """Convert a WindowFunction node to a Window node.""" + """Convert a WindowFunction node to a Window node. + + Also rewrites first -> first_value, last -> last_value. + """ + func = _.func + if isinstance(func, (ops.First, ops.Last)): + if func.where is not None: + raise com.UnsupportedOperationError( + f"`{type(func).__name__.lower()}` with `where` is unsupported " + "in a window function" + ) + cls = FirstValue if isinstance(func, ops.First) else LastValue + func = cls(func.arg) + return Window( how=_.frame.how, - func=_.func, + func=func, start=_.frame.start, end=_.frame.end, group_by=_.frame.group_by, @@ -292,26 +305,6 @@ def rewrite_sample_as_filter(_, **kwargs): return ops.Filter(_.parent, (ops.LessEqual(ops.RandomScalar(), _.fraction),)) -@replace(p.WindowFunction(p.First(x, where=y))) -def rewrite_first_to_first_value(_, x, y, **kwargs): - """Rewrite Ibis's first to first_value when used in a window function.""" - if y is not None: - raise com.UnsupportedOperationError( - "`first` with `where` is unsupported in a window function" - ) - return _.copy(func=FirstValue(x)) - - -@replace(p.WindowFunction(p.Last(x, where=y))) -def rewrite_last_to_last_value(_, x, y, **kwargs): - """Rewrite Ibis's last to last_value when used in a window function.""" - if y is not None: - raise com.UnsupportedOperationError( - "`last` with `where` is unsupported in a window function" - ) - return _.copy(func=LastValue(x)) - - @replace(p.WindowFunction(frame=y @ p.WindowFrame(order_by=()))) def rewrite_empty_order_by_window(_, y, **kwargs): return _.copy(frame=y.copy(order_by=(ops.NULL,))) diff --git a/ibis/backends/sqlite/compiler.py b/ibis/backends/sqlite/compiler.py index 3b18581b6ab9b..fc277b2a44d00 100644 --- a/ibis/backends/sqlite/compiler.py +++ b/ibis/backends/sqlite/compiler.py @@ -10,11 +10,7 @@ from ibis.backends.sql.compiler import NULL, SQLGlotCompiler from ibis.backends.sql.datatypes import SQLiteType from ibis.backends.sql.dialects import SQLite -from ibis.backends.sql.rewrites import ( - rewrite_first_to_first_value, - rewrite_last_to_last_value, - rewrite_sample_as_filter, -) +from ibis.backends.sql.rewrites import rewrite_sample_as_filter from ibis.common.temporal import DateUnit, IntervalUnit @@ -24,12 +20,7 @@ class SQLiteCompiler(SQLGlotCompiler): dialect = SQLite type_mapper = SQLiteType - rewrites = ( - rewrite_sample_as_filter, - rewrite_first_to_first_value, - rewrite_last_to_last_value, - *SQLGlotCompiler.rewrites, - ) + rewrites = (rewrite_sample_as_filter, *SQLGlotCompiler.rewrites) NAN = NULL POS_INF = sge.Literal.number("1e999") diff --git a/ibis/backends/trino/compiler.py b/ibis/backends/trino/compiler.py index 473df45f40a60..67ada7c4ec497 100644 --- a/ibis/backends/trino/compiler.py +++ b/ibis/backends/trino/compiler.py @@ -19,11 +19,7 @@ ) from ibis.backends.sql.datatypes import TrinoType from ibis.backends.sql.dialects import Trino -from ibis.backends.sql.rewrites import ( - exclude_unsupported_window_frame_from_ops, - rewrite_first_to_first_value, - rewrite_last_to_last_value, -) +from ibis.backends.sql.rewrites import exclude_unsupported_window_frame_from_ops class TrinoCompiler(SQLGlotCompiler): @@ -31,12 +27,7 @@ class TrinoCompiler(SQLGlotCompiler): dialect = Trino type_mapper = TrinoType - rewrites = ( - rewrite_first_to_first_value, - rewrite_last_to_last_value, - exclude_unsupported_window_frame_from_ops, - *SQLGlotCompiler.rewrites, - ) + rewrites = (exclude_unsupported_window_frame_from_ops, *SQLGlotCompiler.rewrites) quoted = True NAN = sg.func("nan")