Skip to content

Refactor: Implementing custom query engine (instead of sea-query) - #3

Draft
awolverp wants to merge 83 commits into
masterfrom
refactor/custom-engine
Draft

awolverp wants to merge 83 commits into
masterfrom
refactor/custom-engine

Conversation

@awolverp

Copy link
Copy Markdown
Owner

Based on the feedback I received and the experience I gained, the plan was to switch the library from using sea-query to sqlparser-rs, but it wasn’t adaptable enough.

The decision was made to implement our own custom query engine and take inspiration from existing libraries.

Why is this change needed?

Elimination of all Known Issues

By replacing the core from sea-query with a custom-built one, panic risks are gone. We can implement any feature quickly or fix any problem immediately without waiting for others to address it. I will develop the library carefully and thoroughly so that as few mistakes as possible remain.

Support for more dialects

From the start, we can support over 10 dialects. Currently, 13 dialects have been implemented, though this number may be reduced to a maximum of 10 as the implementation is finalized.
Custom dialect support is also included, allowing you to create your own dialects (with some limitations).

Full control

The library can give you complete and unrestricted control over the queries you build, similar to existing Python query engines.

More complete and comprehensive features

I will try to cover most ASTs. The development priority is as follows: anything added must either be defined by ANSI SQL or supported by at least 3 dialects.
After implementing these, I’ll start covering additional cases as well...

Better performance

Since the query engine becomes fully custom, it can be adapted more closely to Python, eliminating some of the overhead we previously had. For example, with sea-query we had to first convert PyObjects to Rust types before generating SQL, but with the custom query engine we can convert PyObjects directly to SQL wherever needed.

…ive`, and add workspace crate `rapidquery-macros`
Re-export dialects from rapidquery.dialect, add stubs, and fix the
native submodule __name__/__module__ so classes live at
rapidquery._core.dialect.

Make dialect instances compare and hash by variant and repr as
PostgreSQL(). Rename Python class names to DuckDB, PostgreSQL, SQLite,
and MSSQL (Rust variants stay idiomatic).
stdlib json (1M runs): 4.5s -> 2.5s
orjson (1M runs): 4.3s -> 0.3s
Keep enum-vs-class shims only for dialects and serializers
(src/dialect/py.rs, src/data_type/py.rs). Ident, Value, DataType,
and SQL writers live as src modules. Python API is unchanged.
Drop PyIdent/PyValue/PyDataType newtypes. Keep PySqlDialect and
PySerializer as the enum-vs-class shims. Unquote and Asterisk stay
as marker pyclasses.
Encode per-dialect TRY_CAST spelling, `::` support, TRIM form, and
COLLATE form on Dialect. Render TRY_CAST as SAFE_CAST (BigQuery) or
TRYCAST (Teradata) at write time, and error when a dialect does not
support the requested form.

Simplify Cast by dropping FORMAT / AT TIME ZONE and replacing SafeCast
with an opt-in DoubleColon kind. Simplify Trim to a required side plus
an optional character expression instead of `what` plus a character
list.
…alizing, support prefix/suffix parameters for serializers
…date_format, time_format, timestamp_format, uuid_format, json_format; remove prefix/suffix parameters from serializers and collapse SerializerInner into SerializerType
Add a new utility for creating __repr__ outputs: ReprFormatter
Drop support for `Value.__hash__` and `Ident.__hash__`
@awolverp awolverp added the enhancement New feature or request label Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant