Skip to content

lite→Origin sync: CollectionSchema announce skipped for SQL-DDL bitemporal document collections (get_collection_meta returns None) #6

Description

@emanzx

Found while re-testing NodeDB-Lab/nodedb#146 under mae8's real workload. Part (1) of the #146 fix — "lite emits a CollectionSchema frame before the first delta so the collection registers on Origin" — works when the collection is created via the programmatic create_collection, but is silently skipped when the collection is created via SQL DDL:

CREATE COLLECTION entries WITH (bitemporal=true)

which is the path mae8 (and any SQL client) uses. Result: the collection never registers on Origin, SHOW COLLECTIONS stays empty, SELECT … FROM entries is "table not found", and the pushed deltas are non-servable — the exact #146 symptom, via a different entry point.

Root cause

push_collection_schemas (sync outbound) only announces a collection whose metadata it can retrieve:

let Some(meta) = delegate.get_collection_meta(&name).await else {
    // "no persisted metadata; skipping schema announce (implicit CRDT-only collection)"
    continue;
};

get_collection_meta reads collection:{name} from Namespace::Meta. That key is written by create_collection and by the KV DDL path (create_kv_collection) — but not by handle_create_bitemporal_document (query/ddl/document.rs), which only calls set_bitemporal (a bitemporal:{name} flag) + register_collection (CRDT catalog). So a SQL-DDL bitemporal document collection has no CollectionMeta → announce skipped → never registers on Origin.

Repro

  1. Origin on main, sync WS :9090, trust auth.
  2. Lite: CREATE COLLECTION entries WITH (bitemporal=true), then document_put a few docs with sync on.
  3. Origin: SHOW COLLECTIONS; → empty; SELECT count(*) FROM entries; → "table not found". (Deltas are pushed + acked; only the registration/announce is missing.)

Suggested fix

Persist CollectionMeta in handle_create_bitemporal_document, symmetric with create_collection and the KV DDL. Verified locally — with this, the announce fires and SHOW COLLECTIONS shows entries (owner sync-client, collection_homed):

let meta = crate::nodedb::collection::CollectionMeta {
    name: name.clone(),
    collection_type: "document".to_string(),
    created_at_ms: crate::runtime::now_millis(),
    fields: Vec::new(),
    config_json: None,
    descriptor_json: None,
    bitemporal: true,
};
let key = format!("collection:{name}");
let bytes = sonic_rs::to_vec(&meta).map_err(|e| LiteError::Query(format!("serialize: {e}")))?;
self.storage.put(nodedb_types::Namespace::Meta, key.as_bytes(), &bytes).await
    .map_err(|e| LiteError::Query(e.to_string()))?;

Note: registering the collection this way unblocks the round-trip, but it then surfaces a second, deeper gap — only the first document materializes — filed as the reopen on NodeDB-Lab/nodedb#146.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions