From 3bc1b5c56bb450552182e6c7732ccde8b409adfc Mon Sep 17 00:00:00 2001 From: Matthew Shipton Date: Tue, 17 Feb 2026 21:57:02 +0000 Subject: [PATCH 1/2] fix: any and all functions should not have default frame or order_by --- .../snapshots/test_compiler/test_window_filter/out.sql | 5 +++++ ibis/backends/bigquery/tests/unit/test_compiler.py | 7 +++++++ ibis/backends/sql/rewrites.py | 6 +----- 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 ibis/backends/bigquery/tests/unit/snapshots/test_compiler/test_window_filter/out.sql diff --git a/ibis/backends/bigquery/tests/unit/snapshots/test_compiler/test_window_filter/out.sql b/ibis/backends/bigquery/tests/unit/snapshots/test_compiler/test_window_filter/out.sql new file mode 100644 index 000000000000..439ebac40fd9 --- /dev/null +++ b/ibis/backends/bigquery/tests/unit/snapshots/test_compiler/test_window_filter/out.sql @@ -0,0 +1,5 @@ +SELECT + * +FROM `t` AS `t0` +QUALIFY + LOGICAL_OR(`t0`.`a` = 'hello') OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) \ No newline at end of file diff --git a/ibis/backends/bigquery/tests/unit/test_compiler.py b/ibis/backends/bigquery/tests/unit/test_compiler.py index 7f7a3ec43875..e3d38224eff1 100644 --- a/ibis/backends/bigquery/tests/unit/test_compiler.py +++ b/ibis/backends/bigquery/tests/unit/test_compiler.py @@ -711,3 +711,10 @@ def test_unreasonably_long_name(): match="BigQuery does not allow column names longer than 300 characters", ): ibis.to_sql(expr, dialect="bigquery") + + +def test_window_filter(snapshot): + t = ibis.table([("a", "string"), ("x", "int64")], name="t") + expr = t.filter((_.a == "hello").any().over(group_by=_.x)) + result = to_sql(expr) + snapshot.assert_match(result, "out.sql") diff --git a/ibis/backends/sql/rewrites.py b/ibis/backends/sql/rewrites.py index addc87ef7fea..f6001b938bfd 100644 --- a/ibis/backends/sql/rewrites.py +++ b/ibis/backends/sql/rewrites.py @@ -524,11 +524,7 @@ def exclude_unsupported_window_frame_from_rank(_, **kwargs): ) -@replace( - p.WindowFunction( - p.Lag | p.Lead | p.PercentRank | p.CumeDist | p.Any | p.All, start=None - ) -) +@replace(p.WindowFunction(p.Lag | p.Lead | p.PercentRank | p.CumeDist, start=None)) def exclude_unsupported_window_frame_from_ops(_, **kwargs): return _.copy(start=None, end=0, order_by=_.order_by or (ops.NULL,)) From 0592c59e6e5b229776b042c41a32ad757d114a10 Mon Sep 17 00:00:00 2001 From: Matthew Shipton Date: Thu, 26 Feb 2026 23:40:38 +0000 Subject: [PATCH 2/2] fix: rationalize rewrites --- .../bigquery/tests/unit/test_compiler.py | 9 +------- .../sql/compilers/bigquery/__init__.py | 8 +++---- ibis/backends/sql/compilers/exasol.py | 12 +++++------ ibis/backends/sql/compilers/flink.py | 8 +++---- ibis/backends/sql/compilers/impala.py | 4 ++-- ibis/backends/sql/compilers/mssql.py | 8 +++---- ibis/backends/sql/compilers/mysql.py | 12 +++++------ ibis/backends/sql/compilers/oracle.py | 12 ++++++----- ibis/backends/sql/compilers/singlestoredb.py | 12 +++++------ ibis/backends/sql/compilers/snowflake.py | 8 +++---- ibis/backends/sql/compilers/trino.py | 8 +++---- ibis/backends/sql/rewrites.py | 21 ++++++++----------- .../test_all_with_window/athena/out.sql | 3 +++ .../test_all_with_window/bigquery/out.sql | 3 +++ .../test_all_with_window/clickhouse/out.sql | 3 +++ .../test_all_with_window/databricks/out.sql | 3 +++ .../test_all_with_window/datafusion/out.sql | 3 +++ .../test_all_with_window/druid/out.sql | 3 +++ .../test_all_with_window/duckdb/out.sql | 3 +++ .../test_all_with_window/exasol/out.sql | 3 +++ .../test_all_with_window/flink/out.sql | 3 +++ .../test_all_with_window/impala/out.sql | 3 +++ .../test_all_with_window/materialize/out.sql | 3 +++ .../test_all_with_window/mssql/out.sql | 7 +++++++ .../test_all_with_window/mysql/out.sql | 3 +++ .../test_all_with_window/oracle/out.sql | 3 +++ .../test_all_with_window/postgres/out.sql | 3 +++ .../test_all_with_window/pyspark/out.sql | 3 +++ .../test_all_with_window/risingwave/out.sql | 3 +++ .../singlestoredb/out.sql | 3 +++ .../test_all_with_window/snowflake/out.sql | 3 +++ .../test_all_with_window/sqlite/out.sql | 3 +++ .../test_all_with_window/trino/out.sql | 3 +++ .../test_any_with_window/athena/out.sql | 3 +++ .../test_any_with_window/bigquery/out.sql | 3 +++ .../test_any_with_window/clickhouse/out.sql | 3 +++ .../test_any_with_window/databricks/out.sql | 3 +++ .../test_any_with_window/datafusion/out.sql | 3 +++ .../test_any_with_window/druid/out.sql | 3 +++ .../test_any_with_window/duckdb/out.sql | 3 +++ .../test_any_with_window/exasol/out.sql | 3 +++ .../test_any_with_window/flink/out.sql | 3 +++ .../test_any_with_window/impala/out.sql | 3 +++ .../test_any_with_window/materialize/out.sql | 3 +++ .../test_any_with_window/mssql/out.sql | 7 +++++++ .../test_any_with_window/mysql/out.sql | 3 +++ .../test_any_with_window/oracle/out.sql | 3 +++ .../test_any_with_window/postgres/out.sql | 3 +++ .../test_any_with_window/pyspark/out.sql | 3 +++ .../test_any_with_window/risingwave/out.sql | 3 +++ .../singlestoredb/out.sql | 3 +++ .../test_any_with_window/snowflake/out.sql | 3 +++ .../test_any_with_window/sqlite/out.sql | 3 +++ .../test_any_with_window/trino/out.sql | 3 +++ .../exasol/out.sql | 4 ++-- .../impala/out.sql | 4 ++-- .../mysql/out.sql | 10 ++------- .../oracle/out.sql | 4 ++-- .../singlestoredb/out.sql | 10 ++------- .../snowflake/out.sql | 4 ++-- .../test_rewrite_context/bigquery/out.sql | 2 +- .../test_rewrite_context/exasol/out.sql | 2 +- .../test_rewrite_context/flink/out.sql | 5 ++++- .../test_rewrite_context/mssql/out.sql | 2 +- .../test_rewrite_context/mysql/out.sql | 2 +- .../singlestoredb/out.sql | 2 +- ibis/backends/tests/test_sql.py | 18 ++++++++++++++++ 67 files changed, 230 insertions(+), 95 deletions(-) create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/athena/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/bigquery/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/clickhouse/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/databricks/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/datafusion/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/druid/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/duckdb/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/exasol/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/flink/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/impala/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/materialize/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/mssql/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/mysql/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/oracle/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/postgres/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/pyspark/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/risingwave/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/singlestoredb/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/snowflake/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/sqlite/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_all_with_window/trino/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/athena/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/bigquery/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/clickhouse/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/databricks/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/datafusion/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/druid/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/duckdb/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/exasol/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/flink/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/impala/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/materialize/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/mssql/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/mysql/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/oracle/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/postgres/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/pyspark/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/risingwave/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/singlestoredb/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/snowflake/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/sqlite/out.sql create mode 100644 ibis/backends/tests/snapshots/test_sql/test_any_with_window/trino/out.sql diff --git a/ibis/backends/bigquery/tests/unit/test_compiler.py b/ibis/backends/bigquery/tests/unit/test_compiler.py index e3d38224eff1..103ad1588bcc 100644 --- a/ibis/backends/bigquery/tests/unit/test_compiler.py +++ b/ibis/backends/bigquery/tests/unit/test_compiler.py @@ -710,11 +710,4 @@ def test_unreasonably_long_name(): com.IbisError, match="BigQuery does not allow column names longer than 300 characters", ): - ibis.to_sql(expr, dialect="bigquery") - - -def test_window_filter(snapshot): - t = ibis.table([("a", "string"), ("x", "int64")], name="t") - expr = t.filter((_.a == "hello").any().over(group_by=_.x)) - result = to_sql(expr) - snapshot.assert_match(result, "out.sql") + ibis.to_sql(expr, dialect="bigquery") \ No newline at end of file diff --git a/ibis/backends/sql/compilers/bigquery/__init__.py b/ibis/backends/sql/compilers/bigquery/__init__.py index 780a88f8759f..c689943cb0e0 100644 --- a/ibis/backends/sql/compilers/bigquery/__init__.py +++ b/ibis/backends/sql/compilers/bigquery/__init__.py @@ -23,8 +23,8 @@ FirstValue, LastValue, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, + rank_one_to_zero_index, + row_number_one_to_zero_index, lower_sample, split_select_distinct_with_order_by, ) @@ -113,8 +113,8 @@ class BigQueryCompiler(SQLGlotCompiler): rewrites = ( exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_row_number, - exclude_unsupported_window_frame_from_rank, + row_number_one_to_zero_index, + rank_one_to_zero_index, *SQLGlotCompiler.rewrites, ) post_rewrites = (split_select_distinct_with_order_by,) diff --git a/ibis/backends/sql/compilers/exasol.py b/ibis/backends/sql/compilers/exasol.py index 8ae7d3531325..e0da66ae5580 100644 --- a/ibis/backends/sql/compilers/exasol.py +++ b/ibis/backends/sql/compilers/exasol.py @@ -13,9 +13,9 @@ FirstValue, LastValue, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, - rewrite_empty_order_by_window, + rank_one_to_zero_index, + row_number_one_to_zero_index, + add_order_by_to_empty_ranking_window_functions, split_select_distinct_with_order_by, ) @@ -27,9 +27,9 @@ class ExasolCompiler(SQLGlotCompiler): type_mapper = ExasolType rewrites = ( exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, - rewrite_empty_order_by_window, + rank_one_to_zero_index, + row_number_one_to_zero_index, + add_order_by_to_empty_ranking_window_functions, *SQLGlotCompiler.rewrites, ) diff --git a/ibis/backends/sql/compilers/flink.py b/ibis/backends/sql/compilers/flink.py index d8e9599c8d88..b1daa37220ac 100644 --- a/ibis/backends/sql/compilers/flink.py +++ b/ibis/backends/sql/compilers/flink.py @@ -13,8 +13,8 @@ from ibis.backends.sql.dialects import Flink from ibis.backends.sql.rewrites import ( exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, + rank_one_to_zero_index, + row_number_one_to_zero_index, split_select_distinct_with_order_by, ) @@ -61,9 +61,9 @@ class FlinkCompiler(SQLGlotCompiler): agg = FlinkAggGen() rewrites = ( - exclude_unsupported_window_frame_from_row_number, + row_number_one_to_zero_index, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, + rank_one_to_zero_index, *SQLGlotCompiler.rewrites, ) post_rewrites = (split_select_distinct_with_order_by,) diff --git a/ibis/backends/sql/compilers/impala.py b/ibis/backends/sql/compilers/impala.py index 244daca67c89..58a162e8739b 100644 --- a/ibis/backends/sql/compilers/impala.py +++ b/ibis/backends/sql/compilers/impala.py @@ -16,7 +16,7 @@ FirstValue, LastValue, lower_sample, - rewrite_empty_order_by_window, + add_order_by_to_empty_ranking_window_functions, split_select_distinct_with_order_by, ) @@ -27,7 +27,7 @@ class ImpalaCompiler(SQLGlotCompiler): dialect = Impala type_mapper = ImpalaType rewrites = ( - rewrite_empty_order_by_window, + add_order_by_to_empty_ranking_window_functions, *SQLGlotCompiler.rewrites, ) post_rewrites = (split_select_distinct_with_order_by,) diff --git a/ibis/backends/sql/compilers/mssql.py b/ibis/backends/sql/compilers/mssql.py index f6cd773a7b14..61f8d210b853 100644 --- a/ibis/backends/sql/compilers/mssql.py +++ b/ibis/backends/sql/compilers/mssql.py @@ -23,8 +23,8 @@ FirstValue, LastValue, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, + rank_one_to_zero_index, + row_number_one_to_zero_index, lower_sample, p, replace, @@ -70,8 +70,8 @@ class MSSQLCompiler(SQLGlotCompiler): type_mapper = MSSQLType rewrites = ( exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_row_number, - exclude_unsupported_window_frame_from_rank, + row_number_one_to_zero_index, + rank_one_to_zero_index, rewrite_rows_range_order_by_window, *SQLGlotCompiler.rewrites, ) diff --git a/ibis/backends/sql/compilers/mysql.py b/ibis/backends/sql/compilers/mysql.py index 7d134ae2774c..4206101886ca 100644 --- a/ibis/backends/sql/compilers/mysql.py +++ b/ibis/backends/sql/compilers/mysql.py @@ -14,9 +14,9 @@ from ibis.backends.sql.dialects import MySQL from ibis.backends.sql.rewrites import ( exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, - rewrite_empty_order_by_window, + rank_one_to_zero_index, + row_number_one_to_zero_index, + add_order_by_to_empty_ranking_window_functions, ) from ibis.common.patterns import replace from ibis.expr.rewrites import p @@ -48,9 +48,9 @@ class MySQLCompiler(SQLGlotCompiler): rewrites = ( rewrite_limit, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, - rewrite_empty_order_by_window, + rank_one_to_zero_index, + row_number_one_to_zero_index, + add_order_by_to_empty_ranking_window_functions, *SQLGlotCompiler.rewrites, ) diff --git a/ibis/backends/sql/compilers/oracle.py b/ibis/backends/sql/compilers/oracle.py index 636e83a219dd..505da2c40d58 100644 --- a/ibis/backends/sql/compilers/oracle.py +++ b/ibis/backends/sql/compilers/oracle.py @@ -13,11 +13,11 @@ FirstValue, LastValue, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_row_number, + row_number_one_to_zero_index, lower_log2, lower_log10, lower_sample, - rewrite_empty_order_by_window, + add_order_by_to_empty_ranking_window_functions, split_select_distinct_with_order_by, ) @@ -30,9 +30,9 @@ class OracleCompiler(SQLGlotCompiler): dialect = Oracle type_mapper = OracleType rewrites = ( - exclude_unsupported_window_frame_from_row_number, + row_number_one_to_zero_index, exclude_unsupported_window_frame_from_ops, - rewrite_empty_order_by_window, + add_order_by_to_empty_ranking_window_functions, *SQLGlotCompiler.rewrites, ) @@ -419,7 +419,7 @@ def visit_WindowFunction(self, op, *, how, func, start, end, group_by, order_by) if type(op.func) in ( # TODO: figure out REGR_* functions and also manage this list better - # Allowed windowing clause functions + # Allowed windowing clause functions. ops.Mean, # "avg", ops.Correlation, # "corr", ops.Count, # "count", @@ -432,6 +432,8 @@ def visit_WindowFunction(self, op, *, how, func, start, end, group_by, order_by) ops.StandardDev, # "stddev","stddev_pop","stddev_samp", ops.Sum, # "sum", ops.Variance, # "var_pop","var_samp","variance", + ops.Any, # uses "max" + ops.All # uses "min" ): if start is None: start = {} diff --git a/ibis/backends/sql/compilers/singlestoredb.py b/ibis/backends/sql/compilers/singlestoredb.py index df0ccf0f4f8b..204665f85220 100644 --- a/ibis/backends/sql/compilers/singlestoredb.py +++ b/ibis/backends/sql/compilers/singlestoredb.py @@ -13,9 +13,9 @@ from ibis.backends.sql.datatypes import SingleStoreDBType from ibis.backends.sql.rewrites import ( exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, - rewrite_empty_order_by_window, + rank_one_to_zero_index, + row_number_one_to_zero_index, + add_order_by_to_empty_ranking_window_functions, ) from ibis.common.patterns import replace from ibis.expr.rewrites import p @@ -47,9 +47,9 @@ class SingleStoreDBCompiler(MySQLCompiler): rewrites = ( rewrite_limit, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, - rewrite_empty_order_by_window, + rank_one_to_zero_index, + row_number_one_to_zero_index, + add_order_by_to_empty_ranking_window_functions, *MySQLCompiler.rewrites, ) diff --git a/ibis/backends/sql/compilers/snowflake.py b/ibis/backends/sql/compilers/snowflake.py index daa2d86dd2e3..19a040b25471 100644 --- a/ibis/backends/sql/compilers/snowflake.py +++ b/ibis/backends/sql/compilers/snowflake.py @@ -29,11 +29,11 @@ FirstValue, LastValue, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_row_number, + row_number_one_to_zero_index, lower_log2, lower_log10, lower_sample, - rewrite_empty_order_by_window, + add_order_by_to_empty_ranking_window_functions, split_select_distinct_with_order_by, x, ) @@ -84,9 +84,9 @@ class SnowflakeCompiler(SQLGlotCompiler): agg = AggGen(supports_order_by=True) rewrites = ( - exclude_unsupported_window_frame_from_row_number, + row_number_one_to_zero_index, exclude_unsupported_window_frame_from_ops, - rewrite_empty_order_by_window, + add_order_by_to_empty_ranking_window_functions, multiple_args_to_zipped_struct_field_access, *SQLGlotCompiler.rewrites, ) diff --git a/ibis/backends/sql/compilers/trino.py b/ibis/backends/sql/compilers/trino.py index 24c7a0dece70..cffd20def3d0 100644 --- a/ibis/backends/sql/compilers/trino.py +++ b/ibis/backends/sql/compilers/trino.py @@ -25,8 +25,8 @@ FirstValue, LastValue, exclude_unsupported_window_frame_from_ops, - exclude_unsupported_window_frame_from_rank, - exclude_unsupported_window_frame_from_row_number, + rank_one_to_zero_index, + row_number_one_to_zero_index, lower_sample, split_select_distinct_with_order_by, ) @@ -42,8 +42,8 @@ class TrinoCompiler(SQLGlotCompiler): agg = AggGen(supports_filter=True, supports_order_by=True) rewrites = ( - exclude_unsupported_window_frame_from_row_number, - exclude_unsupported_window_frame_from_rank, + row_number_one_to_zero_index, + rank_one_to_zero_index, exclude_unsupported_window_frame_from_ops, *SQLGlotCompiler.rewrites, ) diff --git a/ibis/backends/sql/rewrites.py b/ibis/backends/sql/rewrites.py index 5dcf1ec24dc3..e6cc20e05cbb 100644 --- a/ibis/backends/sql/rewrites.py +++ b/ibis/backends/sql/rewrites.py @@ -507,26 +507,23 @@ def add_one_to_nth_value_input(_, **kwargs): return _.copy(nth=nth) -@replace(p.WindowFunction(order_by=())) -def rewrite_empty_order_by_window(_, **kwargs): - return _.copy(order_by=(ops.NULL,)) - - @replace(p.WindowFunction(p.RowNumber | p.NTile)) -def exclude_unsupported_window_frame_from_row_number(_, **kwargs): - return ops.Subtract(_.copy(start=None, end=0), 1) +def row_number_one_to_zero_index(_, **kwargs): + return ops.Subtract(_, 1) -@replace(p.WindowFunction(p.MinRank | p.DenseRank, start=None)) -def exclude_unsupported_window_frame_from_rank(_, **kwargs): +@replace(p.WindowFunction(p.MinRank | p.DenseRank)) +def rank_one_to_zero_index(_, **kwargs): return ops.Subtract( - _.copy(start=None, end=0, order_by=_.order_by or (ops.NULL,)), 1 + _, 1 ) -@replace(p.WindowFunction(p.Lag | p.Lead | p.PercentRank | p.CumeDist, start=None)) +@replace(p.WindowFunction(p.Lag | p.Lead | p.PercentRank | p.CumeDist)) def exclude_unsupported_window_frame_from_ops(_, **kwargs): - return _.copy(start=None, end=0, order_by=_.order_by or (ops.NULL,)) + """ Some window functions don't make sense with a frame, e.g. + navigation functions, so set an unbounded frame. """ + return _.copy(start=None, end=None) # Rewrite rules for lowering a high-level operation into one composed of more diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/athena/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/athena/out.sql new file mode 100644 index 000000000000..c0cb95a3cc94 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/athena/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/bigquery/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/bigquery/out.sql new file mode 100644 index 000000000000..1dca694df17e --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/bigquery/out.sql @@ -0,0 +1,3 @@ +SELECT + LOGICAL_AND(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `All_a` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/clickhouse/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/clickhouse/out.sql new file mode 100644 index 000000000000..0ac3d0872af0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/clickhouse/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/databricks/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/databricks/out.sql new file mode 100644 index 000000000000..0203934838b8 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/databricks/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `All(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/datafusion/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/datafusion/out.sql new file mode 100644 index 000000000000..c0cb95a3cc94 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/datafusion/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/druid/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/druid/out.sql new file mode 100644 index 000000000000..c0cb95a3cc94 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/druid/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/duckdb/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/duckdb/out.sql new file mode 100644 index 000000000000..4dac59f7073d --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/duckdb/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND(CAST("t0"."a" AS BOOLEAN)) OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/exasol/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/exasol/out.sql new file mode 100644 index 000000000000..0ac3d0872af0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/exasol/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/flink/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/flink/out.sql new file mode 100644 index 000000000000..9a588870f3c2 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/flink/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `All(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/impala/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/impala/out.sql new file mode 100644 index 000000000000..9a588870f3c2 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/impala/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `All(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/materialize/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/materialize/out.sql new file mode 100644 index 000000000000..c0cb95a3cc94 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/materialize/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/mssql/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/mssql/out.sql new file mode 100644 index 000000000000..af3b063104fd --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/mssql/out.sql @@ -0,0 +1,7 @@ +SELECT + IIF([t1].[All(a)] <> 0, 1, 0) AS [All(a)] +FROM ( + SELECT + MIN(IIF([t0].[a] <> 0, 1, 0)) OVER (PARTITION BY [t0].[x] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS [All(a)] + FROM [t] AS [t0] +) AS [t1] \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/mysql/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/mysql/out.sql new file mode 100644 index 000000000000..9a588870f3c2 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/mysql/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `All(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/oracle/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/oracle/out.sql new file mode 100644 index 000000000000..c544dc63a939 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/oracle/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/postgres/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/postgres/out.sql new file mode 100644 index 000000000000..c0cb95a3cc94 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/postgres/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/pyspark/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/pyspark/out.sql new file mode 100644 index 000000000000..0203934838b8 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/pyspark/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `All(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/risingwave/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/risingwave/out.sql new file mode 100644 index 000000000000..c0cb95a3cc94 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/risingwave/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/singlestoredb/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/singlestoredb/out.sql new file mode 100644 index 000000000000..a8bed75a0e60 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/singlestoredb/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN(ABS(`t0`.`a`)) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `All(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/snowflake/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/snowflake/out.sql new file mode 100644 index 000000000000..0ac3d0872af0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/snowflake/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/sqlite/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/sqlite/out.sql new file mode 100644 index 000000000000..0ac3d0872af0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/sqlite/out.sql @@ -0,0 +1,3 @@ +SELECT + MIN("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_all_with_window/trino/out.sql b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/trino/out.sql new file mode 100644 index 000000000000..c0cb95a3cc94 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_all_with_window/trino/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_AND("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "All(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/athena/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/athena/out.sql new file mode 100644 index 000000000000..1d672165dc33 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/athena/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/bigquery/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/bigquery/out.sql new file mode 100644 index 000000000000..28cdb02238ca --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/bigquery/out.sql @@ -0,0 +1,3 @@ +SELECT + LOGICAL_OR(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `Any_a` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/clickhouse/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/clickhouse/out.sql new file mode 100644 index 000000000000..c770432727e0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/clickhouse/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/databricks/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/databricks/out.sql new file mode 100644 index 000000000000..8333054637c7 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/databricks/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `Any(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/datafusion/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/datafusion/out.sql new file mode 100644 index 000000000000..1d672165dc33 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/datafusion/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/druid/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/druid/out.sql new file mode 100644 index 000000000000..1d672165dc33 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/druid/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/duckdb/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/duckdb/out.sql new file mode 100644 index 000000000000..802455efed90 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/duckdb/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR(CAST("t0"."a" AS BOOLEAN)) OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/exasol/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/exasol/out.sql new file mode 100644 index 000000000000..c770432727e0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/exasol/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/flink/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/flink/out.sql new file mode 100644 index 000000000000..0224eda6aba3 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/flink/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `Any(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/impala/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/impala/out.sql new file mode 100644 index 000000000000..0224eda6aba3 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/impala/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `Any(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/materialize/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/materialize/out.sql new file mode 100644 index 000000000000..1d672165dc33 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/materialize/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/mssql/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/mssql/out.sql new file mode 100644 index 000000000000..45b37ff4e7fd --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/mssql/out.sql @@ -0,0 +1,7 @@ +SELECT + IIF([t1].[Any(a)] <> 0, 1, 0) AS [Any(a)] +FROM ( + SELECT + MAX(IIF([t0].[a] <> 0, 1, 0)) OVER (PARTITION BY [t0].[x] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS [Any(a)] + FROM [t] AS [t0] +) AS [t1] \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/mysql/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/mysql/out.sql new file mode 100644 index 000000000000..0224eda6aba3 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/mysql/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `Any(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/oracle/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/oracle/out.sql new file mode 100644 index 000000000000..0f8d93d87ab8 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/oracle/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/postgres/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/postgres/out.sql new file mode 100644 index 000000000000..1d672165dc33 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/postgres/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/pyspark/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/pyspark/out.sql new file mode 100644 index 000000000000..8333054637c7 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/pyspark/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR(`t0`.`a`) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `Any(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/risingwave/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/risingwave/out.sql new file mode 100644 index 000000000000..1d672165dc33 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/risingwave/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/singlestoredb/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/singlestoredb/out.sql new file mode 100644 index 000000000000..db07110d96ce --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/singlestoredb/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX(ABS(`t0`.`a`)) OVER (PARTITION BY `t0`.`x` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `Any(a)` +FROM `t` AS `t0` \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/snowflake/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/snowflake/out.sql new file mode 100644 index 000000000000..c770432727e0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/snowflake/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/sqlite/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/sqlite/out.sql new file mode 100644 index 000000000000..c770432727e0 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/sqlite/out.sql @@ -0,0 +1,3 @@ +SELECT + MAX("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_any_with_window/trino/out.sql b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/trino/out.sql new file mode 100644 index 000000000000..1d672165dc33 --- /dev/null +++ b/ibis/backends/tests/snapshots/test_sql/test_any_with_window/trino/out.sql @@ -0,0 +1,3 @@ +SELECT + BOOL_OR("t0"."a") OVER (PARTITION BY "t0"."x" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Any(a)" +FROM "t" AS "t0" \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/exasol/out.sql b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/exasol/out.sql index 88c5c84cce6d..704c730d726a 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/exasol/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/exasol/out.sql @@ -5,11 +5,11 @@ FROM ( SELECT "t1"."x", "t1"."y", - AVG("t1"."x") OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w + AVG("t1"."x") OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w FROM ( SELECT "t0"."x", - SUM("t0"."x") OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "y" + SUM("t0"."x") OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "y" FROM "t" AS "t0" ) AS "t1" WHERE diff --git a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/impala/out.sql b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/impala/out.sql index 642b68f972ff..33a4d29727f0 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/impala/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/impala/out.sql @@ -5,11 +5,11 @@ FROM ( SELECT `t1`.`x`, `t1`.`y`, - AVG(`t1`.`x`) OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w + AVG(`t1`.`x`) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w FROM ( SELECT `t0`.`x`, - SUM(`t0`.`x`) OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `y` + SUM(`t0`.`x`) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `y` FROM `t` AS `t0` ) AS `t1` WHERE diff --git a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/mysql/out.sql b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/mysql/out.sql index 0cdb41cd36bf..33a4d29727f0 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/mysql/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/mysql/out.sql @@ -5,17 +5,11 @@ FROM ( SELECT `t1`.`x`, `t1`.`y`, - AVG(`t1`.`x`) OVER ( - ORDER BY CASE WHEN NULL IS NULL THEN 1 ELSE 0 END, NULL ASC - ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING - ) AS _w + AVG(`t1`.`x`) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w FROM ( SELECT `t0`.`x`, - SUM(`t0`.`x`) OVER ( - ORDER BY CASE WHEN NULL IS NULL THEN 1 ELSE 0 END, NULL ASC - ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING - ) AS `y` + SUM(`t0`.`x`) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `y` FROM `t` AS `t0` ) AS `t1` WHERE diff --git a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/oracle/out.sql b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/oracle/out.sql index dce34d3769d2..956d186f8ce7 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/oracle/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/oracle/out.sql @@ -5,11 +5,11 @@ FROM ( SELECT "t1"."x", "t1"."y", - AVG("t1"."x") OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w + AVG("t1"."x") OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w FROM ( SELECT "t0"."x", - SUM("t0"."x") OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "y" + SUM("t0"."x") OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "y" FROM "t" "t0" ) "t1" WHERE diff --git a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/singlestoredb/out.sql b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/singlestoredb/out.sql index 2c7d69bbf533..33a4d29727f0 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/singlestoredb/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/singlestoredb/out.sql @@ -5,17 +5,11 @@ FROM ( SELECT `t1`.`x`, `t1`.`y`, - AVG(`t1`.`x`) OVER ( - ORDER BY NULL ASC NULLS LAST - ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING - ) AS _w + AVG(`t1`.`x`) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS _w FROM ( SELECT `t0`.`x`, - SUM(`t0`.`x`) OVER ( - ORDER BY NULL ASC NULLS LAST - ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING - ) AS `y` + SUM(`t0`.`x`) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS `y` FROM `t` AS `t0` ) AS `t1` WHERE diff --git a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/snowflake/out.sql b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/snowflake/out.sql index 9149dca4d3a5..a9bfa1070567 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/snowflake/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_mixed_qualified_and_unqualified_predicates/snowflake/out.sql @@ -3,10 +3,10 @@ SELECT FROM ( SELECT "t0"."x", - SUM("t0"."x") OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "y" + SUM("t0"."x") OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "y" FROM "t" AS "t0" ) AS "t1" WHERE "t1"."y" <= 37 QUALIFY - AVG("t1"."x") OVER (ORDER BY NULL ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) IS NOT NULL \ No newline at end of file + AVG("t1"."x") OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) IS NOT NULL \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/bigquery/out.sql b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/bigquery/out.sql index 97be75ee8986..64d913af5235 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/bigquery/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/bigquery/out.sql @@ -1,4 +1,4 @@ SELECT - NTILE(2) OVER (ORDER BY RAND() ASC) - 1 AS `new_col` + NTILE(2) OVER (ORDER BY RAND() ASC) AS `new_col` FROM `test` AS `t0` LIMIT 10 \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/exasol/out.sql b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/exasol/out.sql index 6712bf5b23fa..4395cc64f9de 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/exasol/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/exasol/out.sql @@ -1,4 +1,4 @@ SELECT - NTILE(2) OVER (ORDER BY RANDOM() ASC) - 1 AS "new_col" + NTILE(2) OVER (ORDER BY RANDOM() ASC) AS "new_col" FROM "test" AS "t0" LIMIT 10 \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/flink/out.sql b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/flink/out.sql index b78291662b87..95afc6974c21 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/flink/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/flink/out.sql @@ -1,4 +1,7 @@ SELECT - NTILE(2) OVER (ORDER BY RAND() ASC NULLS LAST) - 1 AS `new_col` + NTILE(2) OVER ( + ORDER BY RAND() ASC NULLS LAST + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) - 1 AS `new_col` FROM `test` AS `t0` LIMIT 10 \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mssql/out.sql b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mssql/out.sql index 00bca1a41f25..a3be1c8e69fb 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mssql/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mssql/out.sql @@ -1,4 +1,4 @@ SELECT TOP 10 - NTILE(2) OVER (ORDER BY RAND(CHECKSUM(NEWID())) ASC) - 1 AS [new_col] + NTILE(2) OVER (ORDER BY RAND(CHECKSUM(NEWID())) ASC) AS [new_col] FROM [test] AS [t0] \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mysql/out.sql b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mysql/out.sql index 97be75ee8986..64d913af5235 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mysql/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/mysql/out.sql @@ -1,4 +1,4 @@ SELECT - NTILE(2) OVER (ORDER BY RAND() ASC) - 1 AS `new_col` + NTILE(2) OVER (ORDER BY RAND() ASC) AS `new_col` FROM `test` AS `t0` LIMIT 10 \ No newline at end of file diff --git a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/singlestoredb/out.sql b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/singlestoredb/out.sql index b78291662b87..1a5174d60e85 100644 --- a/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/singlestoredb/out.sql +++ b/ibis/backends/tests/snapshots/test_sql/test_rewrite_context/singlestoredb/out.sql @@ -1,4 +1,4 @@ SELECT - NTILE(2) OVER (ORDER BY RAND() ASC NULLS LAST) - 1 AS `new_col` + NTILE(2) OVER (ORDER BY RAND() ASC NULLS LAST) AS `new_col` FROM `test` AS `t0` LIMIT 10 \ No newline at end of file diff --git a/ibis/backends/tests/test_sql.py b/ibis/backends/tests/test_sql.py index ca0a6faf8a58..6e3fa9c6dc85 100644 --- a/ibis/backends/tests/test_sql.py +++ b/ibis/backends/tests/test_sql.py @@ -302,3 +302,21 @@ def test_order_by_no_deference_literals(backend_name, snapshot): o = s.order_by("a", "i", "s") sql = ibis.to_sql(o, dialect=backend_name) snapshot.assert_match(sql, "out.sql") + + +@pytest.mark.parametrize("backend_name", _get_backends_to_test()) +@pytest.mark.notimpl(["polars"], raises=ValueError, reason="not a SQL backend") +def test_any_with_window(backend_name, snapshot): + t = ibis.table([("a", "bool"), ("x", "int64")], name="t") + expr = t.a.any().over(group_by=_.x) + result = ibis.to_sql(expr, dialect=backend_name) + snapshot.assert_match(result, "out.sql") + + +@pytest.mark.parametrize("backend_name", _get_backends_to_test()) +@pytest.mark.notimpl(["polars"], raises=ValueError, reason="not a SQL backend") +def test_all_with_window(backend_name, snapshot): + t = ibis.table([("a", "bool"), ("x", "int64")], name="t") + expr = t.a.all().over(group_by=_.x) + result = ibis.to_sql(expr, dialect=backend_name) + snapshot.assert_match(result, "out.sql") \ No newline at end of file