1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! The one expression evaluator GnitzDB runs — on the engine and in the SQL
//! client alike.
//!
//! A leaf crate below the entire engine: its only in-workspace dependency is
//! `gnitz-wire` (type codes, the OPK codec, the German-string layout, and the
//! bounds-checked byte cursor its blob framing reads through), so both
//! the server and the client-side planner can link it without pulling in
//! storage, the catalog, or the runtime. Its two external crates are
//! dependency-free: `memchr` supplies the substring scan, and `fearless_simd`
//! the vector types and run-time dispatch under the kernels of `simd.rs`.
//! Whatever the engine computes for an expression, the client computes
//! bit-for-bit, because it is the same code.
//!
//! The crate is organized into topic modules with every item re-exported flat at
//! the crate root (`gnitz_expr::FOO`), matching `gnitz-wire`'s leaf-crate shape.
//!
//! What lives here is the whole path from a wire expression blob to evaluated
//! values: [`ExprBuilder`] (which assembles the program), [`LogicalProgram`]
//! (the wire-mirroring form, which both encodes to a blob and decodes back from
//! one), its resolution against a schema, and
//! the morsel-oriented vectorized kernels that evaluate the resolved form — plus
//! the two contracts they read through, [`ColumnLocator`] / [`gnitz_wire::RowSource`] /
//! [`BatchView`] for *where a value physically sits* and [`ColumnTable`] /
//! [`SchemaFacts`] for *what the schema says about it* — the column table an
//! implementor writes, and everything derived from it.
//!
//! `LogicalInstr::to_wire` and `LogicalProgram::decode_instr` are two tables over
//! `ExprOp`; the vocabulary, both tables and the blob framing that carries them
//! all live in `program.rs`, and `tests/program.rs` binds them to each other and
//! to `EXPR_BLOB_VERSION`. `gnitz-wire` keeps only `EXPR_BLOB_VERSION`, the word
//! its `SYS_SCHEMA_DIGEST` const fold must see — it cannot depend on this crate
//! to reach one.
//!
//! Unit tests live in `tests/<module>.rs`, attached with `#[path]` to the module
//! they cover, so each stays that module's own `tests` child and reaches its
//! private items. The `#[ignore]`d retired-instruction benches are in
//! `benches/eval.rs`: they span several modules' kernels, so it attaches at the
//! crate root.
//!
//! # Inlining
//!
//! This crate builds at `opt-level = 1` even in dev (`[profile.dev.package]` in
//! the workspace manifest), but that profile follows the **codegen unit**, not
//! the source file:
//!
//! > A non-generic item is codegen'd in this crate's rlib, at opt-level 1. A
//! > generic one is re-instantiated in the *consuming* crate, at that crate's
//! > opt-level — 0 for gnitz-zset, gnitz-store and gnitz-server in dev.
//!
//! So moving a body out of a generic function into a non-generic one *improves*
//! the debug build, and the reverse costs. `nm -C` on the rlibs is what shows
//! which: a generic body appears as a local (`t`) symbol in each consuming
//! crate's. Anything a generic entry point reaches per row is
//! `#[inline(always)]` regardless.
//!
//! Judge an inlining or kernel change on retired instructions
//! (`perf stat -e instructions:u`), never on wall-clock: timings on the
//! development machines swing far wider than the effects being measured.
pub use scan_filter_bits;
pub use *;
pub use CalendarOp;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;