Skip to content

Single source of truth for connector option classification; retire dot-namespace UNSET heuristic #80

Description

@fightBoxing

Discovered during architecture review of #76 (feat: primary-key upsert/delete + ALTER TABLE schema evolution). Follow-up: has cross-engine implications (Spark / Trino / Ray connectors also write to the Lance dataset config).

Context

#76 introduced LanceCatalog#RESERVED_OPTION_KEYS and
LanceCatalog#isTblProperty(String) to decide which entries of
CatalogBaseTable#getOptions() should be persisted to Lance dataset
config as user TBLPROPERTIES, and which should be treated as
connector/runtime configuration.

Classification lives in two places today:

  • LanceCatalog — hard-coded set: {connector, path, s3-access-key, s3-secret-key, s3-region, s3-endpoint} plus prefix rules
    (read. / write. / index. / vector. / hadoop.).
  • LanceOptions / LanceDynamicTableFactory — requiredOptions() /
    optionalOptions(), generated from ConfigOption constants.

Problems

  1. Dual truth. Adding an option in LanceOptions requires a mirroring
    edit in LanceCatalog, with no compile-time enforcement. Easy to add
    an option and have it silently leak into Lance dataset config as a
    user TBLPROPERTY.
  2. Cross-engine contamination in applyTableProperties. The UNSET
    logic used to iterate dataset.getConfig().keySet() and delete every
    key that was isTblProperty(...) and not in the new options map — so
    a Flink ALTER TABLE t RESET (...) could silently delete metadata
    written by Spark/Trino/Ray. fix(sink): resolve architecture-review must-fix items for upsert sink (#76 follow-up) #77 mitigates this with a "keys containing
    a dot are foreign" heuristic, but the real fix is a namespace-based
    ownership model.
  3. PK metadata namespace collision. Flink persists PK under
    flink.primary-key. Sibling connectors (lance-spark, lance-trino)
    can collide with spark.primary-key / trino.primary-key, producing
    inconsistent PK metadata on the same dataset.

Proposed direction

  1. Introduce LanceOptionsSchema (or ConnectorOptionRegistry) populated
    at classload from LanceOptions.requiredOptions() ∪ LanceOptions.optionalOptions() ∪ hadoop. prefix ∪ a well-known list
    of storage credentials. LanceCatalog#isTblProperty becomes a lookup.
  2. Restrict applyTableProperties' UNSET path to a Flink-owned namespace
    only (e.g. flink.user.*), so foreign engines' config is never
    touched. Retire the "contains a dot" heuristic added in fix(sink): resolve architecture-review must-fix items for upsert sink (#76 follow-up) #77.
  3. Propose upstream in lance-format org that primary-key metadata move
    to a neutral key (e.g. lance.primary-key) and document the
    convention across lance-spark, lance-trino, lance-flink.

Acceptance criteria

  • Adding a new ConfigOption in LanceOptions requires zero edits in
    LanceCatalog.
  • Test: seed a dataset config with a foreign key
    (spark.stats.approx_count = "42"); invoke a Flink
    ALTER TABLE t RESET ('some.flink.prop'); assert the foreign key
    survives. This test should pass without relying on the dot-namespace
    heuristic.
  • Cross-engine PK metadata proposal filed as a separate upstream issue
    (or as part of this one, tagged for lance-format org discussion).

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

    choreMaintenance and choresenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions