feat: support for keyword-only arguments in scalar udfs
Is your feature request related to a problem?
In BigQuery, st_buffer takes several arguments besides the radius property provided by the GeoBuffer op in ibis.
https://github.com/ibis-project/ibis/blob/db1a727b3c4c75e8e4af0f7ef3d0101d26d4450b/ibis/expr/operations/geospatial.py#L362
ST_BUFFER(
geography,
buffer_radius
[, num_seg_quarter_circle => num_segments]
[, use_spheroid => boolean_expression]
[, endcap => endcap_style]
[, side => line_side])
See: https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_buffer for details.
I'd like to workaround this by using @ibis_udf.scalar.builtin, but when I do so, I get an error from BigQuery:
Signature: ST_BUFFER(GEOGRAPHY, FLOAT64, [FLOAT64], [BOOL], [endcap => STRING], [side => STRING])
E Positional argument at 5 is invalid because argument `endcap` can only be referred to by name at [7:3] [{'@type': 'type.googleapis.com/google.rpc.DebugInfo', 'detail': '[INVALID_INPUT] message=[INVALID_INPUT] message=QUERY_ERROR: [No matching signature for function ST_BUFFER\n Argument types: GEOGRAPHY, INT64, FLOAT64, BOOL, STRING, STRING\n Signature: ST_BUFFER(GEOGRAPHY, FLOAT64, [FLOAT64], [BOOL], [endcap => STRING], [side => STRING])
What is the motivation behind your request?
I'd like for bigframes.bigquery to have all possible SQL methods, translated to Python. https://github.com/googleapis/python-bigquery-dataframes/pull/1963 for a work-in-progress PR adding a few of these, if you're curious.
Describe the solution you'd like
I'd like keyword-only arguments in Python to get passed by keyword in SQL. So, the function in this case would look like this:
@ibis_udf.scalar.builtin
def st_buffer(
geography: ibis_dtypes.Geography,
buffer_radius: ibis_dtypes.Float64,
*,
num_seg_quarter_circle: ibis_dtypes.Float64,
use_spheroid: ibis_dtypes.Boolean,
endcap: ibis_dtypes.String,
side: ibis_dtypes.String,
) -> ibis_dtypes.Geography:
...
https://github.com/ibis-project/ibis/blob/db1a727b3c4c75e8e4af0f7ef3d0101d26d4450b/ibis/backends/sql/compilers/base.py#L1263
What version of ibis are you running?
A fork of 10.3.0, I believe, but the relevant operator still has this limitation on HEAD
What backend(s) are you using, if any?
BigQuery
Code of Conduct
- [x] I agree to follow this project's Code of Conduct
I played a little around with this in BigFrames. I've had success getting SQLGlot to generate this syntax by passing args like this:
def visit_GeoRegionStats(self, op, *, arg, raster_id, band, include, options):
args = [arg, raster_id]
if op.band:
args.append(sge.Kwarg(this="band", expression=band))
if op.include:
args.append(sge.Kwarg(this="include", expression=include))
if op.options:
args.append(sge.Kwarg(this="options", expression=options))
return sge.func("ST_REGIONSTATS", *args)