Skip to content

Commit

Permalink
fix(duckdb): parenthesize argument to StructField operation to suppor…
Browse files Browse the repository at this point in the history
…t field access on CASE statements (#8486)
  • Loading branch information
cpcloud authored Feb 28, 2024
1 parent 37c4c7c commit 1371016
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
14 changes: 9 additions & 5 deletions ibis/backends/duckdb/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@
import ibis.common.exceptions as com
import ibis.expr.datatypes as dt
import ibis.expr.operations as ops
from ibis.backends.sql.compiler import (
NULL,
STAR,
SQLGlotCompiler,
)
from ibis.backends.sql.compiler import NULL, STAR, SQLGlotCompiler, paren
from ibis.backends.sql.datatypes import DuckDBType

_INTERVAL_SUFFIXES = {
Expand Down Expand Up @@ -401,3 +397,11 @@ def visit_HexDigest(self, op, *, arg, how):

def visit_StringConcat(self, op, *, arg):
return reduce(lambda x, y: sge.DPipe(this=x, expression=y), arg)

def visit_StructField(self, op, *, arg, field):
if not isinstance(op.arg, (ops.Field, sge.Struct)):
# parenthesize anything that isn't a simple field access
return sge.Dot(
this=paren(arg), expression=sg.to_identifier(field, quoted=self.quoted)
)
return super().visit_StructField(op, arg=arg, field=field)
21 changes: 21 additions & 0 deletions ibis/backends/tests/test_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@

import ibis
import ibis.expr.datatypes as dt
from ibis.backends.tests.errors import (
PsycoPg2InternalError,
PsycoPg2SyntaxError,
Py4JJavaError,
)

pytestmark = [
pytest.mark.never(["mysql", "sqlite", "mssql"], reason="No struct support"),
Expand Down Expand Up @@ -133,3 +138,19 @@ def test_collect_into_struct(alltypes):
val = result.val
assert len(val.loc[result.group == "0"].iat[0]["key"]) == 730
assert len(val.loc[result.group == "1"].iat[0]["key"]) == 730


@pytest.mark.notimpl(
["postgres"], reason="struct literals not implemented", raises=PsycoPg2SyntaxError
)
@pytest.mark.notimpl(
["risingwave"],
reason="struct literals not implemented",
raises=PsycoPg2InternalError,
)
@pytest.mark.notimpl(["flink"], raises=Py4JJavaError, reason="not implemented in ibis")
def test_field_access_after_case(con):
s = ibis.struct({"a": 3})
x = ibis.case().when(True, s).else_(ibis.struct({"a": 4})).end()
y = x.a
assert con.to_pandas(y) == 3

0 comments on commit 1371016

Please sign in to comment.