Skip to content

Replace SQL-string DELETE predicate with typed key encoding in LanceUpsertSink #78

Description

@fightBoxing

Discovered during architecture review of #76 (feat: primary-key upsert/delete + ALTER TABLE schema evolution). Follow-up: not blocking the merge of #76 / #77 but should be addressed before this DELETE path stabilizes.

Context

LanceUpsertSink.buildDeletePredicate translates DELETE events into an
OR-of-AND SQL string fed to Dataset.delete(String). Pragmatic for the
initial PR, not the right long-term shape.

Problems

  1. Type coverage gap. RowDataFieldAccessor supports VarBinaryType
    but formatSqlValue does not; DATE / TIME / TIMESTAMP /
    TIMESTAMP_LTZ / DECIMAL are unsupported on both sides.
  2. Injection surface. Column names are inlined without escaping. Any
    name that collides with a Lance SQL keyword or contains parser-special
    characters is a latent bug.
  3. Formatting fragility. Non-finite floats (NaN, Infinity) had to
    be rejected explicitly. Any future support for BigDecimal would need
    bespoke formatting; the current dispatch is fragile.
  4. Predicate length blow-up. N deleted keys → N OR-joined
    parenthesized triples. Large batches produce arbitrarily long SQL
    strings, pressuring the Lance parser and observability tooling.

Proposed direction (preference order)

  1. mergeInsert with WhenMatched.Delete if the Lance Java SDK
    exposes it — hand Lance a RecordBatch of the primary-key projection,
    let it emit the tombstones. No string round-trip.
  2. col IN (list-encoded batch) for single-column PK. O(N) growth
    with a smaller constant, and a well-understood parser shape.
  3. Otherwise: extract encoding into a tested PrimaryKeyEncoder class,
    share type dispatch with RowDataFieldAccessor so read/delete sides
    cannot drift.

Acceptance criteria

Refs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfeat/deleteDELETE / changelog-mode / CDC handling in the sink

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions