Skip to content

Commit bc7b1e7

Browse files
SNOW-3244422: Fix dense_rank() failure with ValueError on NULL partition values (#4135)
1 parent 48255d9 commit bc7b1e7

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
- Reduced the size of queries generated by certain `DataFrame.join` operations.
1717
- Removed redundant aliases in generated queries (for example, `SELECT "A" AS "A"` is now always simplified to `SELECT "A"`).
1818

19+
### Snowpark Local Testing Updates
20+
21+
#### Bug Fixes
22+
23+
- Fix a bug where `dense_rank()` would fail with `ValueError` on NULL partition values.
24+
1925
## 1.48.0 (2026-03-23)
2026

2127
### Snowpark Python API Updates

src/snowflake/snowpark/mock/_plan.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,7 @@ def _match_pattern(row) -> bool:
26262626
keys,
26272627
sort=False,
26282628
as_index=False,
2629+
dropna=False,
26292630
)
26302631
res_index = []
26312632
for r in res:

tests/mock/test_functions.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
current_date,
2424
current_time,
2525
current_timestamp,
26+
dense_rank,
2627
desc,
2728
get,
2829
is_null,
@@ -514,6 +515,133 @@ def test_rank(session):
514515
)
515516

516517

518+
def test_dense_rank(session):
519+
df = session.create_dataframe(
520+
[
521+
("A", 1),
522+
("A", 1),
523+
("A", 2),
524+
("A", 3),
525+
("B", 2),
526+
("B", 3),
527+
],
528+
["cat", "val"],
529+
)
530+
window_spec = Window.partition_by(col("cat")).order_by(col("val").asc())
531+
result = df.with_column("dense_rank", dense_rank().over(window_spec))
532+
Utils.check_answer(
533+
result,
534+
[
535+
Row("A", 1, 1),
536+
Row("A", 1, 1),
537+
Row("A", 2, 2),
538+
Row("A", 3, 3),
539+
Row("B", 2, 1),
540+
Row("B", 3, 2),
541+
],
542+
)
543+
544+
545+
def test_dense_rank_null_partition(session):
546+
"""dense_rank() should handle NULL partition values (SNOW-3244422)."""
547+
df = session.create_dataframe(
548+
[
549+
("A", 1),
550+
("A", 2),
551+
(None, 3),
552+
(None, 1),
553+
("B", 5),
554+
],
555+
["cat", "val"],
556+
)
557+
window_spec = Window.partition_by(col("cat")).order_by(col("val").asc())
558+
result = df.with_column("dense_rank", dense_rank().over(window_spec))
559+
Utils.check_answer(
560+
result,
561+
[
562+
Row("A", 1, 1),
563+
Row("A", 2, 2),
564+
Row("B", 5, 1),
565+
Row(None, 1, 1),
566+
Row(None, 3, 2),
567+
],
568+
)
569+
570+
571+
def test_rank_null_partition(session):
572+
"""rank() should handle NULL partition values."""
573+
df = session.create_dataframe(
574+
[
575+
("A", 1),
576+
("A", 1),
577+
(None, 2),
578+
(None, 3),
579+
(None, 3),
580+
],
581+
["cat", "val"],
582+
)
583+
window_spec = Window.partition_by(col("cat")).order_by(col("val").asc())
584+
result = df.with_column("rank", rank().over(window_spec))
585+
Utils.check_answer(
586+
result,
587+
[
588+
Row("A", 1, 1),
589+
Row("A", 1, 1),
590+
Row(None, 2, 1),
591+
Row(None, 3, 2),
592+
Row(None, 3, 2),
593+
],
594+
)
595+
596+
597+
def test_row_number_null_partition(session):
598+
"""row_number() should handle NULL partition values."""
599+
df = session.create_dataframe(
600+
[
601+
("A", 1),
602+
("A", 2),
603+
(None, 3),
604+
(None, 1),
605+
],
606+
["cat", "val"],
607+
)
608+
window_spec = Window.partition_by(col("cat")).order_by(col("val").asc())
609+
result = df.with_column("row_num", row_number().over(window_spec))
610+
Utils.check_answer(
611+
result,
612+
[
613+
Row("A", 1, 1),
614+
Row("A", 2, 2),
615+
Row(None, 1, 1),
616+
Row(None, 3, 2),
617+
],
618+
)
619+
620+
621+
def test_window_agg_null_partition(session):
622+
"""Aggregate window functions should handle NULL partition values."""
623+
df = session.create_dataframe(
624+
[
625+
("A", 1),
626+
("A", 3),
627+
(None, 2),
628+
(None, 4),
629+
],
630+
["cat", "val"],
631+
)
632+
window_spec = Window.partition_by(col("cat"))
633+
result = df.with_column("total", sum("val").over(window_spec))
634+
Utils.check_answer(
635+
result,
636+
[
637+
Row("A", 1, 4),
638+
Row("A", 3, 4),
639+
Row(None, 2, 6),
640+
Row(None, 4, 6),
641+
],
642+
)
643+
644+
517645
def test_window_indexing(session):
518646
df = session.create_dataframe(
519647
[

0 commit comments

Comments
 (0)