Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issues closed
Fixes #11525
Description of changes
Adds
The implementation is actually pretty straightforward.
A few open things I'm not sure about
ibis.get_backend()
at op creation time? But that seemed too tricky? There might also be some way to infer the dialect using sqlglot? eg if we hand sqlglot "CAST(NULL AS REAL)" to sqlglot, we should be able to infer this is sqlite dialect?t"CAST({x} AS REAL)"
(eg using sqlite syntax to sql_value() with dialect="duckdb", sqlglot is generous and still parses it. But perhaps we should be more strict and error?ibis.sql_value()
. I went with this, instead of plainibis.sql()
, because I wanted it to be more explicit that this doesn't acceptSELECT
statements. But open to other names.Table.sql()
, the operation actually requires that the expression is bound to a backend, because we actually go fetch the schema of the resulting table by using TYPEOF(). This is very accurate, but does require a backend. In this PR, I don't require a backend, instead just doing some maybe-overly-tricky injectingCAST(NULL AS <dtype>)
instead of the real value. egibis.sql_value(t("{num} + 1))
passes"CAST(NULL AS DOUBLE) + 1"
to sqlglot to infer the datatype. Perhaps we could do some hybrid approach: if there is already a backend, then use that, otherwise fall back to sqlglot? Do we want these two APIs to use the same approach for consistency?This doesn't actually support the original motivating example from the linked issue:
because sqlglot doesn't have complete coverage for introspecting the datatypes of this weird syntax.
We could either
type
kwarg to the op.TemplateSQL (and the publicibis.sql_value()
API). If that is given, then just use that as the dtype, and don't try to use sqlglot to introspect the dtype from the sql.