barrel_query (barrel_docdb v1.0.0)
View SourceQuery compiler and executor for barrel_docdb
Provides functions to compile Datalog-style query specifications into query plans, and execute them against the path index.
Query Syntax:
#{
where => [
{path, [<<"type">>], <<"user">>}, % equality
{path, [<<"org_id">>], '?Org'}, % bind variable
{compare, [<<"age">>], '>', 18}, % comparison
{'and', [...]}, % conjunction
{'or', [...]} % disjunction
],
select => ['?Org', '?Name'], % fields/variables to return
order_by => '?Name', % ordering
limit => 100, % max results
offset => 0 % skip first N
}
Summary
Types
Atoms starting with '?'
Functions
Compile a query specification into a query plan. Returns {ok, QueryPlan} or {error, Reason}.
Dump profiling data to console
Execute a compiled query plan against a database. Returns {ok, Results, LastSeq} or {error, Reason}. Uses a snapshot for read consistency across all index and document reads.
Execute a compiled query plan with chunked execution options. Returns {ok, Results, ResultMeta} where ResultMeta includes: - last_seq: sequence number for change tracking - has_more: true if more results available - continuation: opaque token to resume (only if has_more = true)
Explain a query plan (for debugging/optimization). Returns a map describing the execution strategy.
Extract all paths referenced in a query plan. Used for subscription optimization - only evaluate query when a change affects one of these paths. Returns MQTT-style path patterns for use with barrel_sub.
Get current profiling counters
Check if a value is a logic variable (atom starting with '?')
Check if a document matches a compiled query plan. This is useful for filtering documents in-memory without index access.
Check if a document matches a list of conditions. Simpler API for filtering without needing a compiled query plan.
Normalize a condition to canonical form
Reset profiling counters
Validate a query specification. Returns ok or {error, Reason}.
Types
-type att_info() :: #{name := binary(), content_type := binary(), length := non_neg_integer(), digest := binary(), chunked => boolean(), chunk_size => pos_integer(), chunk_count => pos_integer()}.
-type change() :: map().
-type chunk_opts() :: #{chunk_size => pos_integer(), continuation => binary() | undefined, eventual_consistency => boolean()}.
-type compare_op() :: '>' | '<' | '>=' | '=<' | '=/=' | '=='.
-type condition() :: {path, path(), value()} | {compare, path(), compare_op(), value()} | {'and', [condition()]} | {'or', [condition()]} | {'not', condition()} | {in, path(), [value()]} | {contains, path(), value()} | {exists, path()} | {missing, path()} | {regex, path(), binary()} | {prefix, path(), binary()}.
-type db_name() :: binary().
-type docid() :: binary().
-type logic_var() :: atom().
Atoms starting with '?'
-type query_plan() :: #query_plan{conditions :: [condition()], bindings :: #{logic_var() => path()}, projections :: [projection()], order :: [{path() | logic_var(), asc | desc}], limit :: pos_integer() | undefined, offset :: non_neg_integer(), include_docs :: boolean(), doc_format :: binary | map | json, decoder_fun :: undefined | fun((binary()) -> term()), strategy :: index_seek | index_scan | multi_index | full_scan, flat :: boolean(), id_scan :: undefined | {prefix, binary()} | {range, binary() | undefined, binary() | undefined}}.
-type query_spec() :: #{where => [condition()], select => [projection()], order_by => order_spec() | [order_spec()], limit => pos_integer(), offset => non_neg_integer(), include_docs => boolean(), flat => boolean(), id_prefix => binary(), id_range => {binary() | undefined, binary() | undefined}, doc_format => binary | map | json, decoder_fun => fun((binary()) -> term())}.
-type revid() :: binary().
-type seq() :: barrel_hlc:timestamp().
-type seq_string() :: binary().
-type view_name() :: binary().
Functions
-spec compile(query_spec()) -> {ok, query_plan()} | {error, term()}.
Compile a query specification into a query plan. Returns {ok, QueryPlan} or {error, Reason}.
Dump profiling data to console
-spec execute(barrel_store_rocksdb:db_ref(), db_name(), query_plan()) -> {ok, [map()], seq()} | {error, term()}.
Execute a compiled query plan against a database. Returns {ok, Results, LastSeq} or {error, Reason}. Uses a snapshot for read consistency across all index and document reads.
For unbounded include_docs queries, automatically paginates internally to avoid excessive memory usage from large MultiGet operations.
-spec execute(barrel_store_rocksdb:db_ref(), db_name(), query_plan(), chunk_opts()) -> {ok, [map()], result_meta()} | {error, term()}.
Execute a compiled query plan with chunked execution options. Returns {ok, Results, ResultMeta} where ResultMeta includes: - last_seq: sequence number for change tracking - has_more: true if more results available - continuation: opaque token to resume (only if has_more = true)
Options: - chunk_size: max results per chunk (default 1000) - continuation: resume token from previous call - eventual_consistency: if true, each chunk sees current data (default false)
Example:
%% First chunk
{ok, R1, #{has_more := true, continuation := Token}} =
barrel_query:execute(Store, Db, Plan, #{chunk_size => 100}),
%% Next chunk
{ok, R2, #{has_more := false}} =
barrel_query:execute(Store, Db, Plan, #{continuation => Token}).
-spec explain(query_plan()) -> map().
Explain a query plan (for debugging/optimization). Returns a map describing the execution strategy.
-spec extract_paths(query_plan()) -> [binary()].
Extract all paths referenced in a query plan. Used for subscription optimization - only evaluate query when a change affects one of these paths. Returns MQTT-style path patterns for use with barrel_sub.
Get current profiling counters
Check if a value is a logic variable (atom starting with '?')
-spec match(query_plan(), map()) -> boolean().
Check if a document matches a compiled query plan. This is useful for filtering documents in-memory without index access.
Check if a document matches a list of conditions. Simpler API for filtering without needing a compiled query plan.
Normalize a condition to canonical form
Reset profiling counters
-spec validate_spec(query_spec()) -> ok | {error, term()}.
Validate a query specification. Returns ok or {error, Reason}.