Skip to content

Releases: redbase-app/redb

v3.0.0

29 May 23:53

Choose a tag to compare

Added

  • PG Free: full v2-pvt query engine reaches Pro-parity (0.5.x → 0.6.1).
    The PostgreSQL Free path got the feature-complete v2-pvt module ahead of
    MSSql Free (commits 2026-05-21 … 2026-05-28). Before this series the Free
    path was emitting -- not available in Open Source stubs for several
    preview surfaces and was missing several Pro-only operators. Now in Free
    on PG:

    • Universal "no black box" SQL preview for GroupBy / Window /
      GroupedWindow / Tree-* via two-pass compile (pvt_build_*_sql);
      tree previews resolve the subtree and delegate to the matching non-tree
      preview with a -- Tree …: subtree resolved to N object(s) header.
    • Sql.Function<T> whitelist at the SQL boundary
      (17_pvt_expr.sql) with a
      hardcoded ELSIF chain and RAISE EXCEPTION for non-whitelisted names;
      parser routes Sql.Function<T>(name, args) to
      CustomFunctionExpression (FREE-OVER-PRO §2.4).
    • ValueTuple composite dict keys (Dictionary<(int,int), V>)
      consistently encoded as Base64-JSON on both write and read sides
      (FREE-OVER-PRO §2.2).
    • arr.Length / coll.Count in filters via the array-aware
      FacetFilterBuilder (.$count modifier in Free); e.Tags.Any()
      1-arg form mapped to <field>.$length > 0.
    • Take(0) returns empty instead of ArgumentException.
    • HAVING parser + ArrayGroupBy with PVT agg array unnest
      (19_pvt_agg_expr.sql) —
      fixes 42883 function sum(bigint[]) does not exist;
      26_pvt_array_groupby.sql
      added.
    • ListItem.Value / .Alias via a single LEFT JOIN _list_items
      (v2-pvt 0.6.1) — plan-shape parity with Pro; replaces correlated
      subquery per field.
    • Nested-dict CTE pushdown for Field[key].Child (FREE-OVER-PRO §2.x):
      outer WHERE references the already-built pivot column instead of a
      redundant EXISTS over _values.
    • Auto-deploy of the v2-pvt bundle on version mismatch (see the
      matching item below — same infrastructure serves both PG and MSSql).

    The MSSql Free engine described next ports this PG Free baseline; the
    parity line in the next item ("145/145 parity with PG Free") refers to
    this newly-completed PG Free feature set, not a pre-existing one.

  • MSSql Free: full v2-pvt query engine (0.1.0 → 0.1.3) — 145/145 parity
    with PG Free
    . The old MSSql Free path generated a wide inline CASE WHEN
    aggregate; it is now replaced with the Pro-shape CTE: a single pass over
    _values using MAX(CASE WHEN _id_structure = X AND _array_index IS NULL THEN ...) and a single LEFT JOIN _list_items. All modes present in PG
    Free are implemented: flat/tree, scalar/array/dict fields, ListItem
    (.Id/.Value/.Alias), same-scheme nested POCO (compound path),
    OrderBy/DistinctBy/Take/Skip, GroupBy/HAVING, ArrayGroupBy
    (via OUTER APPLY), array aggregates ($count, $sum/$avg/$min/$max
    over _Long/_Double/_Numeric/_DateTimeOffset), array operators
    ($arrayContains, $arrayAny, $arrayCount*, $arrayAt,
    $arrayStartsWith, etc.), Sql.Function (whitelist), $expr, null
    semantics ($exists/$notNull). The SQL module is split into 27 source
    files under redb.MSSql/sql/v2-pvt/ assembled
    into a single pvt_bundle.sql by MSBuild. Delivery stages: Stage 1 (pivot
    CTE) → 2a (tree TVFs) → 2b (tree provider) → 2c.E (nested-dict accessor
    Field[key].Child) → 0.1.1 LIKE-pattern fix → 0.1.2 string $const
    unwrap + ListItem $arrayContains → 0.1.3 nested-dict CTE pushdown +
    outer WHERE references pivot column instead of a redundant EXISTS.
    Shape parity with Pro throughout: _id_scheme + extra_where +
    tree-filter pushed into inner _objects subquery, narrow-with-nested CTE
    (skips _values JOIN when no scalar sids), stable default ORDER BY when
    paging without an explicit order.

  • Auto-deploy v2-pvt bundle on version mismatch (both databases).
    ISqlDialect gained Query_PvtRequiredVersion() — the semver the embedded
    bundle ships. RedbServiceBase.EnsurePvtModuleDeployedAsync reads
    pvt_module_version() on InitializeAsync(), compares with an exact-match,
    and automatically applies the embedded pvt_bundle.sql resource when the
    deployed version differs. No more manual DROP FUNCTION … CREATE FUNCTION …
    after a SQL change. The MSBuild target ConcatenateSqlFiles regenerates the
    bundle whenever any .sql source changes (hooked to DispatchToInnerBuilds
    for multi-TFM builds; EmbeddedResource uses an explicit LogicalName
    without it MSBuild silently replaces - with _ in resource paths, causing
    GetManifestResourceStream to return null).

  • Pro: GroupBy + HAVING via PVT pipeline on both providers
    (Postgres.Pro + MSSql.Pro)
    . HavingAsync existed in Free but had no Pro
    counterpart. Added full HAVING parser in the shared facet layer
    (FacetFilterBuilder), SQL generation in both Pro providers, and a base
    test suite in
    GroupByHavingTestsBase
    with per-dialect wrappers (PG, PG.Pro, MSSql.Pro). 33/33 HAVING + 6/6
    no-HAVING — all green.

  • Pro: GroupBy over array fields (ArrayGroupBy) — unified implementation
    for Postgres.Pro + MSSql.Pro
    . PG.Pro uses an inline GroupByArray override
    with PVT agg array unnest; MSSql.Pro has its own override.
    GroupBy(items => items.SelectMany(o => o.Skills)) with aggregates works
    on all four tiers (PG Free, PG.Pro, MSSql Free, MSSql.Pro).

  • MSSql Pro: AggregateBatch parity with PG.Pro — non-numeric MIN/MAX and
    inline filter subquery
    . MinAsync/MaxAsync over string/DateTime/Guid
    fields and a Where filter inside a batch aggregation now produce the same
    query shape as PG.Pro (PVT CTE + outer aggregate).

  • MSSql Free: pushdown parity with Pro/PG for expression-form predicates
    and $expr
    — the filter-splitting optimizer
    pvt_split_filter now pushes
    top-level $eq/$ne/$lt/$lte/$gt/$gte/$like/$ilike/$in/$nin/$between/$null/ $notnull/$contains/$startsWith/$endsWith expressions and arbitrary boolean
    $expr trees into the inner _objects o subquery (Shape A) when all
    $field references resolve to kind='base'. If any props field is present
    the node stays in the residual (Shape C). The new classifier
    pvt_expr_is_base_only makes
    this decision; the pushdown SQL itself is generated by the existing
    pvt_build_where_from_json
    walker (extended with a $expr branch). Covered by 4 functional and 3
    shape-inspect tests in
    99_smoke_auto.sql
    (195 PASS / 0 FAIL / 1 SKIP).

Fixed

  • Schema sync now honors Configuration.DefaultStrictDeleteExtra
    (FREE-OVER-PRO §4 #1). Prior to this fix RedbServiceConfiguration.DefaultStrictDeleteExtra
    was set by builders, copied across configuration clones and read from
    appsettings, but no execution-path code consumed it
    SchemeSyncProviderBase.SyncSchemeAsync<T>
    hardcoded strictDeleteExtra: true, so old binaries restarting in a
    multi-version rolling deploy would unconditionally remove _structures
    rows added by the new binary, and every _values row referencing those
    structures along with them. On PostgreSQL this is done via the FK
    _values._id_structure -> _structures._id ON DELETE CASCADE
    (redbPostgre.sql:215). On MSSQL
    the same effect is produced by the INSTEAD OF DELETE trigger
    TR__structures__cascade_values
    (redbMSSQL.sql:717) — the FK
    NO ACTION at redbMSSQL.sql:270
    is a workaround for the MSSQL multiple-cascade-paths restriction, not a
    behavioral difference. SyncSchemeAsync<T> now reads
    now reads Configuration.DefaultStrictDeleteExtra instead. The default
    value is preserved (true) so users on the default config see no
    behavioral change. Behavioral change: the built-in presets
    Development, HighPerformance, and Migration (in
    PredefinedConfigurations.cs)
    already declared DefaultStrictDeleteExtra = false; that setting was
    silently ignored before and now actually takes effect — apps on those
    presets will no longer auto-delete _structures rows missing from the
    Props class on startup.

Added
a fallback to ROW_NUMBER() OVER (PARTITION BY <key> ORDER BY (SELECT 1))

  • WHERE _rn = 1 (symmetric with the Free path), plus support for
    CoalesceExpression in the DistinctBy key.
  • PG v2-pvt 0.6.1: ListItem .Value/.Alias now uses a single
    LEFT JOIN _list_items
    instead of a correlated subquery per field —
    plan-shape parity with Pro. Additionally: nested-dict predicates in the
    outer WHERE now reference _pvt_cte.[<field>] (the already-built pivot
    column) instead of re-running a separate EXISTS over _values.

  • MSSql Free: ORDER BY $expr on base fields no longer produces "constant
    in ORDER BY"
    — two regressions fixed: (1)
    pvt_collect_fields
    did not walk $expr nodes in order entries, so a field like Age was not
    collected, the shape was classified as A, and pvt_b2_expr_sql emitted
    /*unknown-b2-field:Age*/NULL turning Age*2 into a constant; (2)
    [pvt_build_order_conditions](redb.MSSql/sql/v2-pvt...

Read more

v2.0.2

16 May 10:19

Choose a tag to compare

RedBase 2.0.2. See CHANGELOG.md for details. NuGet: https://www.nuget.org/profiles/relikt

v2.0.1

08 May 21:10

Choose a tag to compare

RedBase 2.0.1 — Pro EAV LINQ→SQL fix. License migrated MIT → Apache-2.0 for all OSS packages. Strong-name signing active for Pro assemblies. See CHANGELOG.md for details. NuGet: https://www.nuget.org/profiles/relikt

v1.3.0

04 May 21:03

Choose a tag to compare

What's Changed

Fixed

  • Nullable .Value\ in \WhereRedb\ resolved to wrong column
  • .HasValue\ generated \ ield = true\ instead of \IS NOT NULL\
  • Props cache skipped hashless objects
  • Missing _hash\ in nested object SQL
  • Lexicographic ArrayIndex sorting (10+ items)
  • Duplicate RedbObject in SaveAsync / MERGE duplicate row in ChangeTracking
  • Missing ArrayParentId for nested RedbObject refs
  • Guid field not persisted
  • \DeleteSubtreeAsync\ / \LoadTreeAsync(maxDepth: 1)\ fixes
  • MsSql Pro: null checks, DistinctBy, DELETE stored procedures
  • MsSql Free: WHERE null, OrderBy
  • \get_object_json\ / \�uild_field_json\ fixes
  • KeyGenerator domain isolation, SaveAsync deadlocks, MsSql reader-writer deadlocks
  • SchemeFieldResolver / SyncSchemeAsync cache fixes
  • GroupBy aliased keys, ListItem operators (Postgres + MsSql), Pro OrderBy ListItem
  • GroupBy/Window base field filter crash (9 sites across Postgres.Pro and MsSql.Pro)

Added

  • \save_object_json\ SQL functions (Postgres + MsSql)
  • \DeadlockRetryHelper\ — automatic retry with exponential backoff
  • \BcryptPasswordHasher\ — bcrypt work factor 12

Full changelog: https://github.com/redbase-app/redb/blob/main/CHANGELOG.md

v1.2.15

25 Feb 18:18

Choose a tag to compare

Initial Public Release

Public source code for RedBase open-source packages:

  • redb.CLI - Command-line tool for database management (export, import, schema init)
  • redb.Export - Database export/import library (JSONL/ZIP)
  • redb.Examples - 150+ runnable examples covering CRUD, queries, trees, lists, aggregation, window functions

Install

dotnet tool install --global redb.CLI

See README for full documentation.

NuGet packages: redb.Core | redb.Postgres | redb.MSSql