Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DuckDB sqlglot backend [WIP] #6996

Closed
wants to merge 222 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
222 commits
Select commit Hold shift + click to select a range
13f4567
feat(duckdb): initial cut of sqlglot DuckDB compiler
gforsyth Jul 10, 2023
ec830d6
feat(duckdb): simple and searched case support in sqlglot
gforsyth Aug 30, 2023
783192f
fix(duckdb): handle base table in case statement
gforsyth Aug 30, 2023
610b418
feat(duckdb): ArrayMap and ArrayFilter
gforsyth Aug 30, 2023
d368219
feat(duckdb): fix up window function lags and leads
gforsyth Aug 30, 2023
ec58560
feat(duckdb): implement current_database, list_schemas
gforsyth Aug 30, 2023
f6f2fee
feat(duckdb): fix xor
gforsyth Aug 30, 2023
b27a24f
feat(duckdb): sqlglot exprs for bitwise ops
gforsyth Aug 31, 2023
9a7da6a
feat(duckdb): like, ilike, capitalize as sqlglot exprs
gforsyth Aug 31, 2023
95f0e43
feat(duckdb): literal arrays -> sqlglot
gforsyth Aug 31, 2023
06f4806
feat(duckdb): correct types in arrays, arraydistinct, arraysort
gforsyth Aug 31, 2023
0a2692d
feat(duckdb): sqlglot cast null
gforsyth Aug 31, 2023
83af08d
feat(duckdb): maps in progress...
gforsyth Aug 31, 2023
d1f8d48
feat(duckdb): use new TypeMapper class for parsing dtypes
gforsyth Sep 5, 2023
1863b79
feat(duckdb): improved map support
gforsyth Sep 5, 2023
7b3a208
fix(duckdb): few type conversion updates
gforsyth Sep 5, 2023
760e926
feat(duckdb): quantile and multiquantile
gforsyth Sep 6, 2023
131e905
feat(duckdb): countdistinct and approxcountdistinct
gforsyth Sep 6, 2023
a2bbae8
feat(duckdb): substring sg expr
gforsyth Sep 7, 2023
954fd7c
fix(duckdb): handle sum of comparisons using count
gforsyth Sep 7, 2023
7b9381e
refactor(duckdb): remove remainder of serialize
gforsyth Sep 7, 2023
805aceb
fix(duckdb): nullability in _metadata
gforsyth Sep 7, 2023
b07a496
refactor(duckdb): redo string ops in sqlglot expressions
gforsyth Sep 7, 2023
acb30fd
fix(duckdb): round
gforsyth Sep 7, 2023
570ae7e
fix(duckdb): fix up some date/timestamp stuff re: sqlglot
gforsyth Sep 8, 2023
d70cc50
fix(duckdb): pass timezones as expressions
gforsyth Sep 8, 2023
84905ce
fix(duckdb): remove stringified casts
gforsyth Sep 8, 2023
ad288d2
feat(duckdb): bit aggregations
gforsyth Sep 8, 2023
d65fd3b
feat(duckdb): variance, covariance, stddev aggregation
gforsyth Sep 8, 2023
e0c771b
fix(duckdb): only corr_pop, no corr_samp
gforsyth Sep 8, 2023
8198089
feat(duckdb): group_concat!
gforsyth Sep 8, 2023
dfcd711
feat(duckdb): median and fix count star
gforsyth Sep 8, 2023
42d69dc
fix(duckdb): handle boolean comparisons to corr
gforsyth Sep 8, 2023
a0b753d
feat(duckdb): make sure any and all handle filters
gforsyth Sep 8, 2023
eda2f8d
feat(duckdb): port all reg functions to sqlglot
gforsyth Sep 12, 2023
d4d802c
fix(duckdb): all substring slicing works!
gforsyth Sep 12, 2023
fe9052f
fix(duckdb): handle negative bounds in arrayslice
gforsyth Sep 12, 2023
a9bca69
refactor(duckdb): rearrange and organize by op type
gforsyth Sep 12, 2023
a326c4c
fix(duckdb): strict dtype cast on numeric literal
gforsyth Sep 12, 2023
5894c34
feat(duckdb): decimal infinity and nan
gforsyth Sep 12, 2023
3566c4c
feat(duckdb): create_ and drop_schema
gforsyth Sep 12, 2023
f7924e5
feat(duckdb): use sqlglot for create table expression
gforsyth Sep 12, 2023
1d29494
fix(duckdb): simplify decimal literal
gforsyth Sep 12, 2023
e658b60
chore(duckdb): cleanup linting errors
gforsyth Sep 12, 2023
d8e5e8a
fix(duckdb): fix MapGet and Map Dict
gforsyth Sep 13, 2023
5f8f2ff
feat(duckdb): array repeat
gforsyth Sep 13, 2023
66132ea
fix(duckdb): handle duckdb -> pandas df -> ibis table conversion
gforsyth Sep 13, 2023
c03859f
fix(duckdb): fix array slice with neg index > len(array)
gforsyth Sep 13, 2023
f9c4171
fix(duckdb): fix arrayconcat and array zip
gforsyth Sep 13, 2023
35826e8
test: regen cast sql snapshots
cpcloud Sep 16, 2023
73ed622
feat(duckdb): implement json getitem
cpcloud Sep 16, 2023
3d7cb61
chore: fix percent_rankd and cume_dist
cpcloud Sep 16, 2023
cba7b01
chore: fix rowid
cpcloud Sep 16, 2023
dd2b981
chore: fix dynamic limit/offset
cpcloud Sep 16, 2023
6c37d6c
chore: remove SUPPORTS_MAPS from upstream
cpcloud Sep 16, 2023
c7b9ac1
chore: fix collect with filter
cpcloud Sep 16, 2023
bb96a02
chore: conslidate aggregate filter application and fix reduction oper…
cpcloud Sep 16, 2023
8fbb33c
chore: implement `CountDistinctStar`
cpcloud Sep 16, 2023
6c201fd
chore: clean up approximate aggs and count
cpcloud Sep 16, 2023
f427325
chore: use sg.func in more places
cpcloud Sep 16, 2023
bdacfa9
chore: use `sg.exp.Tuple` instead of string formatting
cpcloud Sep 16, 2023
30c5089
chore: commit ugly sql for now
cpcloud Sep 16, 2023
09114e0
chore: fix scalar parameter translation
cpcloud Sep 16, 2023
db3ede4
chore: implement fillna
cpcloud Sep 16, 2023
f57ea96
chore: fix struct column construction
cpcloud Sep 16, 2023
91c17b9
chore: clean up struct extract a bit
cpcloud Sep 16, 2023
5eb104e
chore: use sg.exp instead of sg.expressions
cpcloud Sep 16, 2023
f86aa56
chore: fix inet and uuid translation
cpcloud Sep 16, 2023
836acd0
chore: promote replacement values to expressions in fillna
cpcloud Sep 16, 2023
2661d3c
chore: allow tuple translation in duckdb
cpcloud Sep 16, 2023
b10025a
chore: expressionize clip
cpcloud Sep 16, 2023
61a5ba6
chore: remove duplicate TODO
cpcloud Sep 16, 2023
f546860
chore: clean up literal casting
cpcloud Sep 16, 2023
9735605
chore: remove already-fixed comment
cpcloud Sep 16, 2023
84d0411
chore: experssionize list_aggr
cpcloud Sep 16, 2023
18b3773
chore: remove TODOs for TODones
cpcloud Sep 16, 2023
240e943
chore: make xor a bit less annoying
cpcloud Sep 16, 2023
f1a1a35
chore: clean up ilike
cpcloud Sep 16, 2023
7922117
revert: chore: clean up literal casting
cpcloud Sep 16, 2023
75e2ec4
chore: expressionize clip
cpcloud Sep 16, 2023
2cb5f12
chore: somehow the dynamic slice test is passing ... but y tho
cpcloud Sep 16, 2023
59bdc67
test(duckdb): fix default backend test
cpcloud Sep 16, 2023
42b177d
chore: remove sqlalchemy type annotations
cpcloud Sep 16, 2023
9db9565
chore: shorten raw_sql a bit
cpcloud Sep 16, 2023
80eae44
chore: clean up current_database and current_schema
cpcloud Sep 16, 2023
f341748
chore: fix udfs
cpcloud Sep 16, 2023
9298c75
chore: remove xor mapping
cpcloud Sep 16, 2023
8f14c29
revert: chore: make xor a bit less annoying
cpcloud Sep 16, 2023
f24bcb0
chore: comment about upstream issue
cpcloud Sep 16, 2023
08c84ae
chore: implement and test `con.insert`
cpcloud Sep 16, 2023
32c26d5
chore: fix all contains except InColumn
cpcloud Sep 16, 2023
8cc2c68
chore: clean up `_JOIN_TYPES`
cpcloud Sep 17, 2023
c1bd46f
style: imports
cpcloud Sep 17, 2023
2ad80f2
chore: eliminate dialect argument in duckdb sqlglot compiler
cpcloud Sep 17, 2023
76bbe34
chore: lift DuckDBType.from_ibis out and fix binary literal test
cpcloud Sep 17, 2023
73f276b
chore: fix macaddr literal translation
cpcloud Sep 17, 2023
f19d13d
chore: shorten literal translation code
cpcloud Sep 17, 2023
c1edafd
chore: fix literal array translation of value type
cpcloud Sep 17, 2023
dcef166
chore: fix approx median
cpcloud Sep 17, 2023
e0f50de
chore: unify decimal and non-decimal literal translation
cpcloud Sep 17, 2023
5e95445
chore: fix isin/notin column
cpcloud Sep 17, 2023
4d0e68d
chore: fix regexp_extract; dialect="duckdb" is required to indicate s…
cpcloud Sep 17, 2023
e806aa6
chore: extract sg.exp.Null() into NULL
cpcloud Sep 17, 2023
d2e9113
chore: move a bunch of functions to automatic registration
cpcloud Sep 17, 2023
06a763e
chore: fix cume_dist translation
cpcloud Sep 17, 2023
dce28cb
chore: move order by keys to sqlglot construct
cpcloud Sep 17, 2023
f3e62bc
chore: translate window functions to sqlglot objects
cpcloud Sep 17, 2023
d4bdd48
chore: regen window function snapshots
cpcloud Sep 17, 2023
8cd8629
chore: delete window function TODO comment
cpcloud Sep 17, 2023
a1d3e44
chore: implement exists/not exists
cpcloud Sep 17, 2023
d6657bb
chore: remove unnecessary `_FRAME_CLAUSE_NOT_ALLOWED` constant
cpcloud Sep 17, 2023
de6717e
chore: fix date_trunc
cpcloud Sep 17, 2023
730a12f
chore: fix column order, which may be returned differently by duckdb
cpcloud Sep 17, 2023
039e9bd
chore: make sure all literal -> table transformations have a consiste…
cpcloud Sep 17, 2023
3d7cb7f
chore: use pandas result getter instead of branch
cpcloud Sep 17, 2023
2445121
chore: reorder columns to schema order instead of forcing them to be …
cpcloud Sep 17, 2023
379e033
chore: handle analytic window functions that require an order by
cpcloud Sep 17, 2023
f51ec45
chore: shorten code a bit
cpcloud Sep 17, 2023
e5e7a8d
chore: fix ms conversion
cpcloud Sep 17, 2023
52bd89c
chore: xfail already xfailing test
cpcloud Sep 17, 2023
b5d3ec1
chore: fix intervals
cpcloud Sep 17, 2023
c6680e3
chore: remove explicit typeof rule
cpcloud Sep 17, 2023
4f8b6d3
chore: fix casting integers to intervals
cpcloud Sep 17, 2023
a7ca399
chore: use arrow
cpcloud Sep 17, 2023
f0c0a9e
chore: fix duckdb xfail
cpcloud Sep 17, 2023
e5f9c88
chore: fix from_ibis decimal
cpcloud Sep 17, 2023
6615b84
chore: replace `list_value` calls with `sg.exp.Array`
cpcloud Sep 17, 2023
9730972
chore: use original conversion code
cpcloud Sep 17, 2023
9aff71c
chore: use original conversion code
cpcloud Sep 17, 2023
6207eac
INVESTIGATE BEFORE MERGE: duckdb returns dateoffsets for interval obj…
cpcloud Sep 17, 2023
b6f1fd0
chore: get most of dot sql tests passing
cpcloud Sep 17, 2023
61b92f8
chore: avoid depending on physical table; eventually the classes shou…
cpcloud Sep 17, 2023
f1e9b1a
chore: let parsing fall through to sqlglot
cpcloud Sep 17, 2023
8d1c119
chore: dot sql all working yay
cpcloud Sep 17, 2023
7cb7990
chore: `sg.expressions` -> `sg.exp`
cpcloud Sep 17, 2023
cf503d7
chore: reuse `_create_temp_view`; down to a single test failure local…
cpcloud Sep 17, 2023
b9e3aae
chore: slightly better comment
cpcloud Sep 17, 2023
17932f1
chore: remove bogus `external_tables` argument
cpcloud Sep 17, 2023
9b2ffe7
chore: remove dialect from set ops
cpcloud Sep 17, 2023
0fef49d
chore: remove timezone handling code; it may actually be correct, fil…
cpcloud Sep 17, 2023
d3f8d91
chore: get builtin agg udfs working
cpcloud Sep 17, 2023
6b37361
chore: remove the need to pass where
cpcloud Sep 17, 2023
a23c33c
chore: clean up aggregates
cpcloud Sep 17, 2023
473e331
chore: unwrap aliases in struct field access
cpcloud Sep 17, 2023
207152d
chore: remove last vestiges of `Schema.apply_to`
cpcloud Sep 17, 2023
9ea9f97
chore: fix strip functions
cpcloud Sep 17, 2023
7635882
chore: ensure that null handling is done with IdenticalTo when `==` a…
cpcloud Sep 17, 2023
544aa9d
chore: fix array concat to preserve existing behavior
cpcloud Sep 17, 2023
2c3ad0a
chore: fix __xor__
cpcloud Sep 17, 2023
286b3bc
chore: adjust `show_sql` doctest
cpcloud Sep 17, 2023
3b464ff
chore: get outta here clickhouse
cpcloud Sep 17, 2023
706d881
chore: remove a bunch of version checking in the duckdb backend
cpcloud Sep 18, 2023
baf7e75
chore: note why `_define_udf_translation_rules` is not necessary
cpcloud Sep 18, 2023
1cb2f52
chore: avoid overkill use of arrow for current_database and current_s…
cpcloud Sep 18, 2023
569eda2
chore: remove unnecessary `DuckDBTable` class
cpcloud Sep 18, 2023
4572702
chore: fix broken xor
cpcloud Sep 18, 2023
2014244
chore: remove `aliases or {}` pattern
cpcloud Sep 18, 2023
3251285
style: rename `pieces` to `args`
cpcloud Sep 18, 2023
085c212
chore: rename duplicate `_scalar_udf` rule to `_agg_udf`
cpcloud Sep 18, 2023
1c4e840
chore: remove _fully_qualified_name use
cpcloud Sep 18, 2023
7add166
chore: fix listing tables, schemas and databases
cpcloud Sep 18, 2023
c155b44
chore: make accessing schema information the same as upstream because…
cpcloud Sep 18, 2023
b7c9cb3
style: improve udf translation rule docstring
cpcloud Sep 18, 2023
4845aa4
chore: allow running a single doctest with `just doctest`
cpcloud Sep 18, 2023
dca77c5
chore: handle time literals
cpcloud Sep 18, 2023
d1bd037
revert: chore: allow running a single doctest with `just doctest`
cpcloud Sep 18, 2023
10aa6c4
chore: remove redundant str call
cpcloud Sep 18, 2023
6a48731
chore: unbind in `to_sql` call to decouple backend translation
cpcloud Sep 18, 2023
10729fa
chore: update for enforced naming for all expressions including literals
cpcloud Sep 18, 2023
626fdc6
docs: avoid executing `.close()` as it is not necessary for the new d…
cpcloud Sep 18, 2023
fdf2579
chore: avoid unnecessary additional node before finding base table
cpcloud Sep 18, 2023
6a582c8
chore: factor out unaliasing
cpcloud Sep 18, 2023
2552790
chore: fix renaming of pandas backend single column results
cpcloud Sep 18, 2023
c3ef2dd
chore: fix insert by runing pre execute hooks before compiling
cpcloud Sep 18, 2023
86fc6f4
chore: clean up append
cpcloud Sep 18, 2023
f4ee1e1
chore: consolidate under the banner of `raw_sql`
cpcloud Sep 18, 2023
800d36c
chore: skip missing snowflake deps
cpcloud Sep 18, 2023
bc701e0
chore: handle expressions in values of replacements mapping for fillna
cpcloud Sep 18, 2023
f41d379
chore: handle expressions in values of replacements mapping for filln…
cpcloud Sep 18, 2023
de0755d
chore: handle expressions in values of replacements mapping for filln…
cpcloud Sep 18, 2023
1dee6af
fixup! chore: handle expressions in values of replacements mapping fo…
cpcloud Sep 18, 2023
84a7662
chore(clickhouse): force column names to match the schema because col…
cpcloud Sep 18, 2023
696ecb1
chore: bring back annoying workaround for ddb 8375
cpcloud Sep 18, 2023
2a9d918
chore(bigquery): force column names to match the expression schema
cpcloud Sep 18, 2023
c55fb67
chore(pyspark): handle intervals before raw
cpcloud Sep 18, 2023
3dc9ccf
chore(snowflake): force column names to match the expression schema
cpcloud Sep 18, 2023
b68dfe6
test(duckdb): fix error type on extension download failure when sandb…
cpcloud Sep 18, 2023
566e399
chore(deps): remove duckdb-engine from deps
cpcloud Sep 18, 2023
6779ee3
fixup! chore(deps): remove duckdb-engine from deps
cpcloud Sep 18, 2023
5ce93dd
ci: remove duckdb-engine from ci
cpcloud Sep 18, 2023
787acdc
chore: translate the table full stop, for table array view, instead o…
cpcloud Sep 18, 2023
2eab3b8
chore: handle subquery only on selects
cpcloud Sep 18, 2023
eeaa2aa
chore: bring back decimal warning
cpcloud Sep 18, 2023
76d78ce
chore: remove unused `_sql` function
cpcloud Sep 18, 2023
c87f9dd
chore: avoid reprojection of dataframe when converting to ibis types
cpcloud Sep 18, 2023
8bfe95b
chore: impala fix naming
cpcloud Sep 19, 2023
7461847
chore: generate group by indices instead of repeating the expression
cpcloud Sep 19, 2023
aaa25dd
fixup! chore: generate group by indices instead of repeating the expr…
cpcloud Sep 19, 2023
46c0cda
chore: remove use of `sg.condition` in favor of `sg.and_`
cpcloud Sep 19, 2023
fe72a41
chore: pluck out `aliases` kwarg
cpcloud Sep 19, 2023
9b9b5e4
chore: remove `remove_aliases` kwarg from duckdb compiler
cpcloud Sep 19, 2023
d9e9484
chore(duckdb): use `sg_literal` everywhere
cpcloud Sep 19, 2023
5be5c91
chore: unalias everything that should not have `expr AS name`
cpcloud Sep 19, 2023
282bdfb
chore: remove rebase screwups
cpcloud Sep 26, 2023
189e427
chore: bring back unalias temporarily
cpcloud Sep 26, 2023
29aeac5
chore: regen sql
cpcloud Sep 26, 2023
f46cb0f
chore: raw_sql
cpcloud Sep 26, 2023
1360eaa
chore: fix for new array function representation
cpcloud Sep 26, 2023
a2b848d
chore: regen passing tpch queries
cpcloud Sep 26, 2023
ff5855e
chore: fix clip
cpcloud Sep 26, 2023
995ff19
chore: add base compiler functionality
cpcloud Sep 26, 2023
d61d530
chore(clickhouse): move to base compiler functionality
cpcloud Sep 26, 2023
fe96efc
chore(duckdb): move to base compiler functionality
cpcloud Sep 26, 2023
b689374
chore: get almost everything working
cpcloud Sep 26, 2023
ed74968
chore: regen sql
cpcloud Sep 26, 2023
8676b65
chore: remove duplicate clickhouse xfail
cpcloud Sep 26, 2023
9da4977
chore: remove dead code and unnecessary `lit` calls
cpcloud Sep 26, 2023
c50f4d8
chore: clean up kw
cpcloud Sep 26, 2023
159fe97
chore: remove unalias function
cpcloud Sep 26, 2023
f4f4054
chore: add pattern to transform empty percent rank et al
cpcloud Sep 26, 2023
fcfaad8
chore(clickhouse): regen sql
cpcloud Sep 26, 2023
dbf34e5
chore: more lit and array cleanup
cpcloud Sep 26, 2023
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
2 changes: 1 addition & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"addLabels": ["bigquery"]
},
{
"matchPackagePatterns": ["duckdb", "duckdb-engine"],
"matchPackagePatterns": ["duckdb"],
"addLabels": ["duckdb"]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to/extending/sql.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ with closing(con.raw_sql("CREATE TEMP TABLE my_table AS SELECT * FROM RANGE(10)"

Here's an example:

```{python}
```python
Copy link
Member

Choose a reason for hiding this comment

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

I need to revisit the return of raw_sql for duckdb, it doesn't seem like it can ever be closed when using raw duckdb.

cur = con.raw_sql("CREATE TEMP TABLE t AS SELECT * FROM RANGE(10)")
cur.close() # <1>
```
Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/base/sqlglot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ def make_cast(
converter: SqlglotType,
) -> Callable[[sg.exp.Expression, dt.DataType], sg.exp.Cast]:
def cast(arg: sg.exp.Expression, to: dt.DataType) -> sg.exp.Cast:
return sg.cast(arg, to=converter.from_ibis(to))
return sg.cast(_to_sqlglot(arg), to=converter.from_ibis(to))

return cast
Empty file.
177 changes: 177 additions & 0 deletions ibis/backends/base/sqlglot/compiler/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
"""ClickHouse ibis expression to sqlglot compiler.

The compiler is built with a few `singledispatch` functions:

1. `translate` for table expressions
1. `translate` for table nodes
1. `translate_rel`
1. `translate_val`

## `translate`

### Expression Implementation

The table expression implementation of `translate` is a pass through to the
node implementation.

### Node Implementation

There's a single `ops.Node` implementation for `ops.TableNode`s instances.

This function:

1. Topologically sorts the expression graph.
1. Seeds the compilation cache with in-degree-zero table names.
1. Iterates though nodes with at least one in-degree and places the result
in the compilation cache. The cache is used to construct `ops.TableNode`
keyword arguments to the current translation rule.

## `translate_rel`

Translates a table operation given already-translated table inputs.

If a table node needs to translate value expressions, for example, an
`ops.Aggregation` that rule is responsible for calling `translate_val`.

## `translate_val`

Recurses top-down and translates the arguments of the value expression and uses
those as input to construct the output.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

import sqlglot as sg

import ibis.expr.analysis as an
import ibis.expr.operations as ops
import ibis.expr.types as ir
from ibis.common.patterns import Call
from ibis.expr.analysis import c, p, x, y

if TYPE_CHECKING:
from collections.abc import Mapping


a = Call.namespace(an)


def translate(
op: ops.TableNode,
*,
params: Mapping[ir.Value, Any],
translate_rel,
translate_val,
) -> sg.exp.Expression:
"""Translate an ibis operation to a sqlglot expression.

Parameters
----------
op
An ibis `TableNode`
params
A mapping of expressions to concrete values
translate_rel
Relation node translator
translate_val
Value node translator

Returns
-------
sqlglot.expressions.Expression
A sqlglot expression
"""

def _translate_node(node, *args, **kwargs):
if isinstance(node, ops.Value):
return translate_val(node, *args, **kwargs)
assert isinstance(node, ops.TableNode)
return translate_rel(node, *args, **kwargs)

alias_index = 0
aliases = {}

def fn(node, _, **kwargs):
nonlocal alias_index

result = _translate_node(node, aliases=aliases, **kwargs)

if not isinstance(node, ops.TableNode):
return result

# don't alias the root node
if node is not op:
aliases[node] = f"t{alias_index:d}"
alias_index += 1

if alias := aliases.get(node):
try:
return result.subquery(alias=alias)
except AttributeError:
return sg.alias(result, alias=alias)
else:
return result

# substitute parameters immediately to avoid having to define a
# ScalarParameter translation rule
#
# this lets us avoid threading `params` through every `translate_val` call
# only to be used in the one place it would be needed: the ScalarParameter
# `translate_val` rule
params = {param.op(): value for param, value in params.items()}
replace_literals = p.ScalarParameter >> (
lambda op, _: ops.Literal(value=params[op], dtype=op.dtype)
)

# rewrite cumulative functions to window functions, so that we don't have
# to think about handling them in the compiler, we need only compile window
# functions
replace_cumulative_ops = p.WindowFunction(
x @ p.Cumulative, y
) >> a.cumulative_to_window(x, y)

# replace the right side of InColumn into a scalar subquery for sql
# backends
replace_in_column_with_table_array_view = p.InColumn >> (
lambda op, _: op.__class__(
op.value,
ops.TableArrayView(
ops.Selection(
table=an.find_first_base_table(op.options), selections=(op.options,)
)
),
)
)

# replace any checks against an empty right side of the IN operation with
# `False`
replace_empty_in_values_with_false = p.InValues(x, ()) >> c.Literal(
False, dtype="bool"
)

replace_notexists_subquery_with_not_exists = p.NotExistsSubquery(x, y) >> c.Not(
c.ExistsSubquery(x, y)
)

add_order_by_to_window_funcs = p.WindowFunction(
p.PercentRank(x) | p.RankBase(x) | p.CumeDist(x),
(
p.WindowFrame(..., order_by=())
>> (lambda op, ctx: op.copy(order_by=(ctx[x],)))
),
)

op = op.replace(
replace_literals
| replace_cumulative_ops
| replace_in_column_with_table_array_view
| replace_empty_in_values_with_false
| replace_notexists_subquery_with_not_exists
| add_order_by_to_window_funcs
)
# apply translate rules in topological order
results = op.map(fn, filter=(ops.TableNode, ops.Value))
node = results[op]
return node.this if isinstance(node, sg.exp.Subquery) else node
10 changes: 8 additions & 2 deletions ibis/backends/base/sqlglot/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,17 @@

@classmethod
def _from_ibis_Decimal(cls, dtype: dt.Decimal) -> sge.DataType:
if (precision := dtype.precision) is None:
precision = cls.default_decimal_precision

Check warning on line 279 in ibis/backends/base/sqlglot/datatypes.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/base/sqlglot/datatypes.py#L279

Added line #L279 was not covered by tests

if (scale := dtype.scale) is None:
scale = cls.default_decimal_scale

Check warning on line 282 in ibis/backends/base/sqlglot/datatypes.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/base/sqlglot/datatypes.py#L282

Added line #L282 was not covered by tests

return sge.DataType(
this=typecode.DECIMAL,
expressions=[
sge.DataTypeParam(this=sge.Literal.number(dtype.precision)),
sge.DataTypeParam(this=sge.Literal.number(dtype.scale)),
sge.DataTypeParam(this=sge.Literal.number(precision)),
sge.DataTypeParam(this=sge.Literal.number(scale)),
Copy link
Member

Choose a reason for hiding this comment

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

This change is to fix an actual bug which is that we weren't handling default precision and scale when converting from ibis decimal types to sqlglot decimal types

],
)

Expand Down
1 change: 1 addition & 0 deletions ibis/backends/bigquery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@
def fetch_from_cursor(self, cursor, schema):
arrow_t = self._cursor_to_arrow(cursor)
df = arrow_t.to_pandas(timestamp_as_object=True)
df.columns = list(schema.names)

Check warning on line 440 in ibis/backends/bigquery/__init__.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/bigquery/__init__.py#L440

Added line #L440 was not covered by tests
return PandasData.convert_table(df, schema)

def _cursor_to_arrow(
Expand Down
2 changes: 2 additions & 0 deletions ibis/backends/clickhouse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ def execute(

if df.empty:
df = pd.DataFrame(columns=schema.names)
else:
df.columns = list(schema.names)

# TODO: remove the extra conversion
#
Expand Down
Loading
Loading