You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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.
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
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.
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).
Context
#76 introduced
LanceCatalog#RESERVED_OPTION_KEYSandLanceCatalog#isTblProperty(String)to decide which entries ofCatalogBaseTable#getOptions()should be persisted to Lance datasetconfig 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 fromConfigOptionconstants.Problems
LanceOptionsrequires a mirroringedit in
LanceCatalog, with no compile-time enforcement. Easy to addan option and have it silently leak into Lance dataset config as a
user TBLPROPERTY.
applyTableProperties. The UNSETlogic used to iterate
dataset.getConfig().keySet()and delete everykey that was
isTblProperty(...)and not in the new options map — soa Flink
ALTER TABLE t RESET (...)could silently delete metadatawritten 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.
flink.primary-key. Sibling connectors (lance-spark,lance-trino)can collide with
spark.primary-key/trino.primary-key, producinginconsistent PK metadata on the same dataset.
Proposed direction
LanceOptionsSchema(orConnectorOptionRegistry) populatedat classload from
LanceOptions.requiredOptions() ∪ LanceOptions.optionalOptions() ∪ hadoop.prefix ∪ a well-known listof storage credentials.
LanceCatalog#isTblPropertybecomes a lookup.applyTableProperties' UNSET path to a Flink-owned namespaceonly (e.g.
flink.user.*), so foreign engines' config is nevertouched. Retire the "contains a dot" heuristic added in fix(sink): resolve architecture-review must-fix items for upsert sink (#76 follow-up) #77.
lance-formatorg that primary-key metadata moveto a neutral key (e.g.
lance.primary-key) and document theconvention across
lance-spark,lance-trino,lance-flink.Acceptance criteria
ConfigOptioninLanceOptionsrequires zero edits inLanceCatalog.(
spark.stats.approx_count = "42"); invoke a FlinkALTER TABLE t RESET ('some.flink.prop'); assert the foreign keysurvives. This test should pass without relying on the dot-namespace
heuristic.
(or as part of this one, tagged for
lance-formatorg discussion).Refs
isForeignNamespacedKeyas an interim protection).