Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ibis/backends/sql/rewrites.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,15 @@ def filter_to_select(_, **kwargs):
)


def is_constant(value: ops.Value) -> bool:
return not value.relations and not value.find(ops.Impure, filter=ops.Value)


@replace(p.Sort)
def sort_to_select(_, **kwargs):
"""Convert a Sort node to a Select node."""
return Select(_.parent, selections=_.values, sort_keys=_.keys)
non_constant_keys = tuple(key for key in _.keys if not is_constant(key.expr))
return Select(_.parent, selections=_.values, sort_keys=non_constant_keys)


@replace(p.Distinct)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
SELECT
*
"t0"."f",
"t0"."c"
FROM "star1" AS "t0"
ORDER BY
"t0"."f" ASC
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT
"t0"."f",
"t0"."c"
FROM "star1" AS "t0"
ORDER BY
"t0"."f" ASC
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT
"t0"."f",
"t0"."c"
FROM "star1" AS "t0"
ORDER BY
"t0"."f" + 1 ASC
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SELECT
"t0"."f",
"t0"."c"
FROM "star1" AS "t0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SELECT
"t0"."f",
"t0"."c"
FROM "star1" AS "t0"
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
SELECT
*
FROM "star1" AS "t0"
FROM (
SELECT
"t1"."f",
"t1"."c"
FROM (
SELECT
*
FROM "star1" AS "t0"
ORDER BY
RANDOM() ASC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there now a subquery? Is that correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you see how the actual expression changed here? Before the expression was just t.order_by(ibis.random()). Now it is the more complicated t.order_by(ibis.random()).select("f", "c").order_by(ibis.random()).

This new version is equivalent to t.select("f", "c").order_by(ibis.random()) which is SELECT "t0"."f", "t0"."c" FROM "star1" AS "t0" ORDER BY RANDOM() ASC. For this simple case we could drop the internal order by, and then merge the two selects. But my initial gut reaction is that there are cases where the internal select result depends on the internal order by, and so in general we can't just drop the inner select? So in general I would say this subquery is unnecessary, but correct.

) AS "t1"
) AS "t2"
ORDER BY
RANDOM() ASC
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
SELECT
*
FROM (
SELECT
"t1"."f",
"t1"."c"
FROM (
SELECT
*
FROM "star1" AS "t0"
ORDER BY
RANDOM() ASC,
"t0"."f" ASC
) AS "t1"
) AS "t2"
ORDER BY
RANDOM() ASC,
"t2"."f" ASC
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
SELECT
*
FROM (
SELECT
"t1"."f",
"t1"."c"
FROM (
SELECT
*
FROM "star1" AS "t0"
ORDER BY
RANDOM() ASC
) AS "t1"
) AS "t2"
ORDER BY
RANDOM() ASC
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
SELECT
*
FROM (
SELECT
"t1"."f",
"t1"."c"
FROM (
SELECT
*
FROM "star1" AS "t0"
ORDER BY
RANDOM() + 1 ASC
) AS "t1"
) AS "t2"
ORDER BY
RANDOM() + 1 ASC
17 changes: 14 additions & 3 deletions ibis/backends/tests/sql/test_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,22 @@ def test_aggregate(star1, expr_fn, snapshot):

@pytest.mark.parametrize(
"key",
["f", ibis.random()],
ids=["column", "random"],
[
pytest.param("f", id="column"),
pytest.param(ibis._.f + 1, id="column_derived"),
pytest.param(ibis.random(), id="random"),
pytest.param(ibis.random() + 1, id="random_derived"),
pytest.param(ibis.literal(5), id="literal"),
pytest.param(ibis.literal(5) + 1, id="literal_derived"),
pytest.param((ibis.random(), "f"), id="random_and_column"),
pytest.param((ibis.random(), ibis.literal(5)), id="random_and_literal"),
pytest.param(("f", ibis.literal(5)), id="column_and_literal"),
],
)
def test_order_by(star1, key, snapshot):
expr = star1.order_by(key)
# We are doing two order_bys to test that the rewrite that drops constant keys
# works at all levels of the expression tree.
expr = star1.order_by(key).select("f", "c").order_by(key)
snapshot.assert_match(to_sql(expr), "out.sql")


Expand Down