snowflakedb / snowflakedb/snowpark-python

SNOW-781480: group_by and groupBy methods add undesired cols to select

Open
#771 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug triaged
Dominant language
Python
Stars
341
Forks
155
Avg merge
4d 16h
Merged PRs (30d)
27

Description

Expected behaviour:

The following Python code

from logging import getLogger, INFO, FileHandler
from snowflake.snowpark.session import Session
from snowflake.snowpark.functions import col, count, to_date

# set logger to info, and save queries to log-file
getLogger("snowflake.connector.cursor").setLevel(INFO)
getLogger("snowflake.connector.cursor").addHandler(FileHandler("cursor.log"))

# start session, change query length such that full query is displayed
session = Session.builder.configs(
    dict(
        authenticator="externalbrowser",
        account="",
        user="",
        role="",
        warehouse="",
        database="",
        schema="",
        log_max_query_length=1000000,
    )
).create()

# run query
session.table("table").group_by(col("col_a")).agg(count("*").as_("num")).collect()

Should result in the first query shown below, but actually results in the second (see generated log-file), note how col_a is added to the select, which is undesired.

SELECT count(1) AS "NUM" FROM ( SELECT  *  FROM table) GROUP BY "COL_A"
SELECT "COL_A", count(1) AS "NUM" FROM ( SELECT  *  FROM table) GROUP BY "COL_A"

Why this is a problem

Because of this, it is not possible to rename a column. The following Python code, for example:

session.table("table").group_by(col("event_day")).agg(
    to_date(col("event_date")).as_("event_day"), count("*")
).collect()

Would ideally result in the first query shown below, but actually results in the second query, which gives an error, because the first select statement (EVENT_DAY) is undefined. It is also not possible to rename the column in the group_by as this is not allowed.

SELECT to_date("EVENT_DATE") AS "EVENT_DAY", count(1) AS "COUNT(LITERAL())" FROM ( SELECT  *  FROM table) GROUP BY "EVENT_DAY"
SELECT "EVENT_DAY", to_date("EVENT_DATE") AS "EVENT_DAY", count(1) AS "COUNT(LITERAL())" FROM ( SELECT  *  FROM table) GROUP BY "EVENT_DAY"

Work-around

The way to circumvent this is to start with a select statement:

session.table("table").select(
    to_date(col("event_date")).as_("event_day")
).group_by(col("event_day")).agg(count("*").as_("num")).collect()

but this results in a nested select statement, which is slower

SELECT "EVENT_DAY", count(1) AS "NUM" FROM ( SELECT to_date("EVENT_DATE") AS "EVENT_DAY" FROM table) GROUP BY "EVENT_DAY"

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the group_by(...).agg(...) examples and inspect the generated SQL in cursor.log. Start by tracing the group_by and groupBy query-generation paths, then verify that grouping columns are not added to the select list and that the column-renaming example succeeds without the workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, sql
Domain
data-engineering, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.