Skip to content

Add C++ query builder#4664

Open
JasonAtClockwork wants to merge 15 commits into
masterfrom
jlarabie/cpp-query-builder
Open

Add C++ query builder#4664
JasonAtClockwork wants to merge 15 commits into
masterfrom
jlarabie/cpp-query-builder

Conversation

@JasonAtClockwork
Copy link
Copy Markdown
Contributor

@JasonAtClockwork JasonAtClockwork commented Mar 18, 2026

Description of Changes

  • Added a query builder for C++ module bindings
    • Added query-builder table/filter/join types
    • Added semijoin support with compile-time checks for lookup-table and indexed-field usage
    • Added support for returning query-builder queries from C++ views
    • Hooked query-builder metadata into the C++ table/view macros and V10 module-def path
  • Added test coverage for the new C++ query-builder behavior
    • Compile tests for pass/fail cases
    • SQL tests for generated query output
    • Added a C++ test module for view primary key coverage
  • Update: Switched the core to pass the columns and index-columns metadata with the table source for better client-side codegen to have some shared code between server + client.

API and ABI breaking changes

  • No intended API or ABI breaking changes
  • Adds a new public query-builder API to the C++ bindings
  • C++ views can now return query-builder query types in addition to materialized row results

Expected complexity level and risk

3 - Mostly contained to C++ bindings, but it touches macros, view registration/serialization, and module-def generation, so there are a few places where the pieces need to stay in sync.

Testing

I've done end to end testing of I think every type as well as built some tests to confirm the SQL output.

  • Run the C++ query-builder SQL tests [crates/bindings-cpp/tests/query-builder-compile/run_query_builder_compile_tests.sh]
  • Smoke test a generated C++ module using query-builder views

@JasonAtClockwork JasonAtClockwork self-assigned this Mar 18, 2026
@JasonAtClockwork JasonAtClockwork linked an issue Mar 18, 2026 that may be closed by this pull request
@JasonAtClockwork JasonAtClockwork marked this pull request as ready for review March 18, 2026 20:04
@JasonAtClockwork JasonAtClockwork added documentation Improvements or additions to documentation backward-compatible docs deploy whenever Docs updates that aren't tied to a specific release, and should be deployed when convenient. labels Mar 18, 2026
Copy link
Copy Markdown
Contributor

@rekhoff rekhoff left a comment

Choose a reason for hiding this comment

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

Looks good to me. Some fairly minor nits here.

Comment thread crates/bindings-cpp/include/spacetimedb/query_builder/expr.h
Comment thread docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md Outdated
JasonAtClockwork and others added 5 commits March 20, 2026 12:42
@JasonAtClockwork
Copy link
Copy Markdown
Contributor Author

Updated the core query builder to carry generated column and index-column metadata alongside each table source. This was needed so downstream codegen can reason about the source shape directly instead of reconstructing it indirectly.

In practice, that lets the client generator produce source-aware query authoring APIs, expose the right fields and lookup surfaces, and support a much better Blueprint/C++ developer experience without maintaining a separate query-builder model.

@JasonAtClockwork JasonAtClockwork added docs deploy ASAP Important docs changes that should be deployed immediately. and removed docs deploy whenever Docs updates that aren't tied to a specific release, and should be deployed when convenient. labels Apr 15, 2026
Copy link
Copy Markdown
Contributor

@rekhoff rekhoff left a comment

Choose a reason for hiding this comment

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

Just a few items

Comment thread crates/bindings-cpp/include/spacetimedb/query_builder/join.h Outdated
Comment thread crates/bindings-cpp/include/spacetimedb/query_builder/join.h Outdated
Comment thread crates/bindings-cpp/include/spacetimedb/query_builder/table.h
Copy link
Copy Markdown
Contributor

@rekhoff rekhoff left a comment

Choose a reason for hiding this comment

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

Just one minor nit, otherwise looks good

Comment thread crates/bindings-cpp/include/spacetimedb/query_builder/expr.h Outdated
JasonAtClockwork and others added 2 commits April 22, 2026 13:23
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
Signed-off-by: Jason Larabie <jason@clockworklabs.io>
# Conflicts:
#	crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h
Comment thread crates/bindings-cpp/include/spacetimedb/query_builder/expr.h
// `where_ix` based on the predicate signature.
template<typename TFn>
[[nodiscard]] auto where(TFn&& predicate) const {
if constexpr (std::is_invocable_v<TFn, const TCols&, const TIxCols&>) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why does the where predicate take both TCols and TIxCols? Index columns aren't relevant for where right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Index columns aren’t required for where semantically. This split is there so chained queries don’t lose access to indexed-column predicates after earlier query steps. This isn't necessary for the pure C++ query builder, but I'm reusing this on the Unreal C++ side and want to keep them aligned which means a little extra API.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a way to keep the index cols internal and not part of the user facing api? To maintain consistency with the other query builders?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is there a way to keep the index cols internal and not part of the user facing api? To maintain consistency with the other query builders?

Yes and I should have done that! It's been cleaned up now so the where_ix/where_col are no longer in the public api.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backward-compatible docs deploy ASAP Important docs changes that should be deployed immediately. documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Unreal] Module bindings for query builder

4 participants