datafusion_inline_functions
Define a function inside one SQL query, then reuse it throughout that query. This Python package uses Rust to expand those calls into ordinary Apache DataFusion 54.x SQL before execution.
DataFusion does not accept this package's WITH FUNCTION syntax directly. Without it, you might repeat a formatting expression:
SELECT
CASE WHEN ready_hours < 0.1 THEN '<0.1' ELSE CAST(ready_hours AS VARCHAR) END AS ready,
CASE WHEN done_hours < 0.1 THEN '<0.1' ELSE CAST(done_hours AS VARCHAR) END AS done
FROM production
With expand_sql, define that expression once:
WITH FUNCTION hours_text(hours) AS (
CASE WHEN hours < 0.1 THEN '<0.1' ELSE CAST(hours AS VARCHAR) END
)
SELECT hours_text(ready_hours) AS ready, hours_text(done_hours) AS done
FROM production
The result is still one SQL query. There is no database function registration, extra database request, or function state shared between queries. The Rust code runs during SQL preparation; DataFusion executes the resulting expressions.
Install and try it
Requires Python 3.11+. Install the package and DataFusion:
python -m pip install datafusion_inline_functions 'datafusion>=54,<55'
Wheels are provided for macOS Apple Silicon and Linux x86-64/ARM64. Other platforms build from source and require Rust.
The distribution name and import name are both datafusion_inline_functions. DataFusion is installed separately to execute queries; the expander itself only transforms strings.
This complete Python example needs no input files or database setup:
from datafusion import SessionContext, SQLOptions
from datafusion_inline_functions import expand_sql
sql = """
WITH FUNCTION twice(x) AS (x * 2)
SELECT twice(3 + 1) AS answer
"""
expanded = expand_sql(sql)
print(expanded)
# SELECT ((3 + 1) * 2) AS answer
options = (
SQLOptions()
.with_allow_ddl(False)
.with_allow_dml(False)
.with_allow_statements(False)
)
print(SessionContext().sql(expanded, options=options).to_pydict())
# {'answer': [8]}
expand_sql(sql: str) -> str returns SQL text; it does not execute it. Invalid declarations or unsupported calls raise ValueError.
Multiple functions
Use one WITH, separate declarations with commas, and repeat FUNCTION for each definition. Local functions can call other local functions:
WITH FUNCTION twice(x) AS (x * 2),
FUNCTION twice_plus_one(x) AS (twice(x) + 1)
SELECT twice(3) AS a, twice_plus_one(3) AS b
After expansion and execution, .to_pylist()[0] returns {'a': 6, 'b': 7}. Recursive calls, including functions calling each other in a cycle, are rejected during expansion.
More than arithmetic
Functions can return structs, for example to keep a numeric sort value beside display text:
WITH FUNCTION cell(value) AS (
struct(value AS sort, CAST(value AS VARCHAR) AS text)
)
SELECT cell(12) AS ready, cell(3) AS done
After expansion and execution, .to_pylist()[0] returns this row:
{'ready': {'sort': 12, 'text': '12'}, 'done': {'sort': 3, 'text': '3'}}
You can also use CASE, nested calls to other local functions, typed parameters/results, ordinary WITH queries, and scalar SELECT subqueries. See syntax and binding rules for examples. Definitions belong to one query; this package does not provide a global function catalog or resolve reusable named queries for your application.
Boundaries to know
- Queries without a leading
WITH FUNCTIONpass through byte-for-byte unchanged. Queries with definitions are parsed and rewritten; their original comments and formatting are not retained. - These are expression macros: an argument used twice is inserted twice. A call such as
f(random())can evaluaterandom()more than once. - Subquery bodies require qualified column references and reject alias collisions. Unsupported binding forms fail explicitly; table-returning functions and procedural statements are not supported.
- Expansion is not a read-only SQL validator. Keep DataFusion's
SQLOptionschecks when read-only execution matters.
The supported engine target is DataFusion 54.x, not arbitrary SQL dialects. The implementation uses Apache's sqlparser Rust crate; the core expander has no SQLGlot or SQLMesh dependency. An optional editors extra provides a SQLGlot adapter for original source positions.
For application integration, see reusable queries and dynamic SQL. For building, testing, and the pypi upload command, see development and publishing.
Metadata
Release files for datafusion-inline-functions 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| datafusion_inline_functions-0.1.0.tar.gz | 73.4 kB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| datafusion_inline_functions-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| datafusion_inline_functions-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| datafusion_inline_functions-0.1.0-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 11.7 MB
Release files / datafusion_inline_functions-0.1.0.tar.gz
| Download URL | datafusion_inline_functions-0.1.0.tar.gz |
|---|---|
| Size | 73.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b5b211f0085aef6ed5d07b82b7e1ff62c90d4e9a8ebfa55fe44881bea92c78ab
|
|
BLAKE2b-256 checksum How to use checksums |
9a798b003a114c00ed045c398e5fd4d7d34a1c3c766f1162db6808a25af7928c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / datafusion_inline_functions-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | datafusion_inline_functions-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0c6d3ee861eaed3803329aeb9a9aa4e237070ce8473e92cb8c411b3dbbcc6ed5
|
|
BLAKE2b-256 checksum How to use checksums |
e3ddb56247549ab23e8f023b69dfe661a49ff46323ccd66a64b9b04228fd0914
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / datafusion_inline_functions-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | datafusion_inline_functions-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 3.8 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
71ef568ffc529ee21da966601b06024b058acb408ff5fb40e5e83c9006623fb4
|
|
BLAKE2b-256 checksum How to use checksums |
2fa0bff6ba627674e75de63666eaa22b51a9a94f632ce0127b9fa5e0e7332155
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / datafusion_inline_functions-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | datafusion_inline_functions-0.1.0-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
e6d7f83b95bcdea0dbe2f471ad6ab9e06aebc4ba58aad8e3e7d99e25213ef704
|
|
BLAKE2b-256 checksum How to use checksums |
6db274a31af841437712bd843478fad5374e228c41a0b998fd3c8c59ae85da89
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|