Skip to content

Commit 534eae7

Browse files
authored
Fix Lance ATTACH table discovery after SHOW TABLES (#133)
1 parent 509991a commit 534eae7

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

src/lance_storage.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,10 @@ class LanceSchemaEntry final : public DuckSchemaEntry {
469469
: DuckSchemaEntry(catalog, info), directory_ns(std::move(directory_ns)),
470470
rest_ns(std::move(rest_ns)) {}
471471

472+
void SetTableDefaultGenerator(DefaultGenerator *generator) {
473+
table_default_generator = generator;
474+
}
475+
472476
void Alter(CatalogTransaction transaction, AlterInfo &info) override {
473477
auto &set = GetCatalogSet(info.GetCatalogType());
474478
auto entry = set.GetEntry(transaction, info.name);
@@ -654,6 +658,16 @@ class LanceSchemaEntry final : public DuckSchemaEntry {
654658
throw InternalException(
655659
"Could not drop element because of an internal error");
656660
}
661+
662+
// DropEntry with a system (committed) CatalogTransaction leaves a committed
663+
// tombstone behind. This blocks subsequent lazy discovery of a recreated
664+
// dataset with the same name, because CatalogSet::GetEntryDetailed will
665+
// find the tombstone and never consult the default generator. Since ATTACH
666+
// TYPE LANCE catalogs are ephemeral, we can eagerly clean up the entry
667+
// chain (old entry + tombstone).
668+
set.CleanupEntry(*existing_entry);
669+
670+
InvalidateTableDefaults();
657671
}
658672

659673
optional_ptr<CatalogEntry> CreateTable(CatalogTransaction transaction,
@@ -723,6 +737,7 @@ class LanceSchemaEntry final : public DuckSchemaEntry {
723737
exists ? existing_id : (prefixed_id.empty() ? leaf_id : prefixed_id);
724738
if (create_info.on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT &&
725739
exists) {
740+
InvalidateTableDefaults();
726741
return nullptr;
727742
}
728743
if (create_info.on_conflict == OnCreateConflict::ERROR_ON_CONFLICT &&
@@ -790,6 +805,7 @@ class LanceSchemaEntry final : public DuckSchemaEntry {
790805
DirectoryNamespaceTableExists(*directory_ns, create_info.table);
791806
if (create_info.on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT &&
792807
exists) {
808+
InvalidateTableDefaults();
793809
return nullptr;
794810
}
795811
if (create_info.on_conflict == OnCreateConflict::ERROR_ON_CONFLICT &&
@@ -866,12 +882,21 @@ class LanceSchemaEntry final : public DuckSchemaEntry {
866882
}
867883
}
868884

885+
InvalidateTableDefaults();
869886
return nullptr;
870887
}
871888

872889
private:
890+
void InvalidateTableDefaults() {
891+
if (!table_default_generator) {
892+
return;
893+
}
894+
table_default_generator->created_all_entries = false;
895+
}
896+
873897
shared_ptr<LanceDirectoryNamespaceConfig> directory_ns;
874898
shared_ptr<LanceRestNamespaceConfig> rest_ns;
899+
DefaultGenerator *table_default_generator = nullptr;
875900
};
876901

877902
class LanceDuckCatalog final : public DuckCatalog {
@@ -1529,6 +1554,7 @@ LanceStorageAttach(optional_ptr<StorageExtensionInfo>, ClientContext &context,
15291554
catalog->ReplaceDefaultSchemaWithLanceSchema(system_transaction);
15301555
auto &schema = catalog->GetSchema(system_transaction, DEFAULT_SCHEMA);
15311556

1557+
auto &lance_schema = schema.Cast<LanceSchemaEntry>();
15321558
auto &duck_schema = schema.Cast<DuckSchemaEntry>();
15331559
auto &catalog_set = duck_schema.GetCatalogSet(CatalogType::TABLE_ENTRY);
15341560

@@ -1541,7 +1567,9 @@ LanceStorageAttach(optional_ptr<StorageExtensionInfo>, ClientContext &context,
15411567
std::move(api_key), delimiter, bearer_token_override, api_key_override,
15421568
headers_tsv);
15431569
}
1570+
auto *generator_ptr = generator.get();
15441571
catalog_set.SetDefaultGenerator(std::move(generator));
1572+
lance_schema.SetTableDefaultGenerator(generator_ptr);
15451573

15461574
(void)name;
15471575
return std::move(catalog);

test/sql/namespace_create_table.test

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
require lance
66

77
statement ok
8-
COPY (SELECT 1::BIGINT AS id) TO 'test/.tmp/attach_create_table_seed.lance' (FORMAT lance, mode 'overwrite');
8+
COPY (SELECT 1::BIGINT AS id) TO 'test/.tmp/nsroot_create_table_125/attach_create_table_seed.lance' (FORMAT lance, mode 'overwrite');
99

1010
statement ok
11-
ATTACH 'test/.tmp' AS ns (TYPE LANCE);
11+
ATTACH 'test/.tmp/nsroot_create_table_125' AS ns (TYPE LANCE);
1212

1313
statement ok
1414
CREATE OR REPLACE TABLE ns.main.attach_create_table_empty (id BIGINT, s VARCHAR);
@@ -30,7 +30,7 @@ SELECT count(*) FROM ns.main.attach_create_table_ctas
3030
2
3131

3232
query I
33-
SELECT count(*) FROM 'test/.tmp/attach_create_table_ctas.lance'
33+
SELECT count(*) FROM 'test/.tmp/nsroot_create_table_125/attach_create_table_ctas.lance'
3434
----
3535
2
3636

@@ -52,5 +52,26 @@ SELECT sum(id) FROM ns.main.attach_create_table_ctas
5252
----
5353
3
5454

55+
statement ok
56+
DROP TABLE IF EXISTS ns.main.attach_create_table_after_show;
57+
58+
query T
59+
SHOW TABLES FROM ns.main
60+
----
61+
attach_create_table_ctas
62+
attach_create_table_empty
63+
attach_create_table_seed
64+
65+
statement ok
66+
CREATE TABLE ns.main.attach_create_table_after_show (id BIGINT);
67+
68+
statement ok
69+
INSERT INTO ns.main.attach_create_table_after_show VALUES (1), (2);
70+
71+
query I
72+
SELECT count(*) FROM ns.main.attach_create_table_after_show
73+
----
74+
2
75+
5576
statement ok
5677
DETACH ns;

0 commit comments

Comments
 (0)