Almost all components of RisingWave are developed in rust, and they are split to several crates:
config
contains default configurations for servers.prost
contains generated protobuf rust code, e.g. grpc definition and message definition.stream
contains our stream compute engine, read Stream Engine for more details.batch
contains our batch compute engine for queries against materialized views.frontend
contains our SQL query planner and scheduler.storage
contains our cloud native storage engine, read State Store Overview for more details.meta
contains our meta engine, read Meta Service for more details.utils
contains several independent util crates which helps to simplify development. We plan to publish them to crates.io in future when they are more mature.cmd
contains all binaries, andcmd_all
contains the all-in-one binaryrisingwave
.risedevtool
is an awesome developer tool for RisingWave, read RiseDev Guide for more details.
RisingWave uses a lot of macros to simplify development.
You may choose the read to macro definition directly,
but something complementary / easier is to use cargo expand
to expand the macro and read the expanded code.
You can also setup rust-analyzer
in the editor to expand macros on the fly.
See https://rust-analyzer.github.io/manual.html#expand-macro-recursively.
This is the better option if you want to understand the code interactively.
For instance, within meta::manager::catalog::CatalogManager::finish_create_table_procedure
there's a call to the macro commit_meta!()
.
To understand it, first I dump the expanded code to a file:
cargo expand -p risingwave_meta > meta.rs
Then I search for the function call finish_create_table_procedure
in my editor,
and compare the original code with the expanded code in meta.rs
.
From there I can see that it does the following, followed by some instrumentation code which can be ignored:
async {
tables.apply_to_txn(&mut trx)?;
self.env.meta_store().txn(trx).await?;
tables.commit();
MetaResult::Ok(())
}.instrument(/* ... */)
The other example would be the #[aggregate]
procedural macro.
To understand it, first I dump the expanded code to a file:
cargo expand -p risingwave_expr > expr.rs
Then we identify the #[aggregate]
macro call to examine. In this case it's string_agg
.
First, we know that cargo expand
merges the individual modules into one big file, namespaced by the module name.
In this case string_agg
is its own module, so we can search for mod string_agg
in the expr.rs
we just generated.
We can see that the expanded string_agg
now also contains extern fn string_agg_varchar_varchar_varchar
.
Reading the code we understand now that it does the following:
- Register it to a global registry for aggregates.
- "it" here refers to an
AggFuncSig
, whose definition we can checkout. - Of note is that it will generate an anonymous struct which implements the
AggregateFunction
trait.