Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/include/storage/sqlite_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
namespace duckdb {
class SQLiteCatalog;
class SQLiteTableEntry;
class SQLiteCatalogMap;

class SQLiteTransaction : public Transaction {
public:
Expand All @@ -36,7 +37,7 @@ class SQLiteTransaction : public Transaction {
SQLiteCatalog &sqlite_catalog;
SQLiteDB *db;
SQLiteDB owned_db;
case_insensitive_map_t<unique_ptr<CatalogEntry>> catalog_entries;
unique_ptr<SQLiteCatalogMap> catalog_map;
};

} // namespace duckdb
51 changes: 43 additions & 8 deletions src/storage/sqlite_transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,42 @@

namespace duckdb {

class SQLiteCatalogMap {
public:
optional_ptr<CatalogEntry> InsertEntry(const string &entry_name, unique_ptr<CatalogEntry> entry);
optional_ptr<CatalogEntry> GetEntry(const string &entry_name);
void EraseEntry(const string &entry_name);
private:
mutex lock;
case_insensitive_map_t<unique_ptr<CatalogEntry>> catalog_entries;
};


optional_ptr<CatalogEntry> SQLiteCatalogMap::InsertEntry(const string &entry_name, unique_ptr<CatalogEntry> catalog_entry) {
lock_guard<mutex> guard(lock);
auto entry = catalog_entries.find(entry_name);
if (entry != catalog_entries.end()) {
return entry->second.get();
}
auto &result = *catalog_entry;
catalog_entries[entry_name] = std::move(catalog_entry);
return result;
}

optional_ptr<CatalogEntry> SQLiteCatalogMap::GetEntry(const string &entry_name) {
lock_guard<mutex> guard(lock);
auto entry = catalog_entries.find(entry_name);
if (entry != catalog_entries.end()) {
return entry->second.get();
}
return nullptr;
}

void SQLiteCatalogMap::EraseEntry(const string &entry_name) {
lock_guard<mutex> guard(lock);
catalog_entries.erase(entry_name);
}

SQLiteTransaction::SQLiteTransaction(SQLiteCatalog &sqlite_catalog, TransactionManager &manager, ClientContext &context)
: Transaction(manager, context), sqlite_catalog(sqlite_catalog) {
if (sqlite_catalog.InMemory()) {
Expand All @@ -25,6 +61,7 @@ SQLiteTransaction::SQLiteTransaction(SQLiteCatalog &sqlite_catalog, TransactionM
owned_db = SQLiteDB::Open(sqlite_catalog.path, sqlite_catalog.options, true);
db = &owned_db;
}
catalog_map = make_uniq<SQLiteCatalogMap>();
}

SQLiteTransaction::~SQLiteTransaction() {
Expand Down Expand Up @@ -106,9 +143,9 @@ unique_ptr<CreateIndexInfo> FromCreateIndex(ClientContext &context, TableCatalog
}

optional_ptr<CatalogEntry> SQLiteTransaction::GetCatalogEntry(const string &entry_name) {
auto entry = catalog_entries.find(entry_name);
if (entry != catalog_entries.end()) {
return entry->second.get();
auto entry = catalog_map->GetEntry(entry_name);
if (entry) {
return entry;
}
// catalog entry not found - look up table in main SQLite database
auto type = db->GetEntryType(entry_name);
Expand Down Expand Up @@ -169,13 +206,11 @@ optional_ptr<CatalogEntry> SQLiteTransaction::GetCatalogEntry(const string &entr
default:
throw InternalException("Unrecognized catalog entry type");
}
auto result_ptr = result.get();
catalog_entries[entry_name] = std::move(result);
return result_ptr;
return catalog_map->InsertEntry(entry_name, std::move(result));
}

void SQLiteTransaction::ClearTableEntry(const string &table_name) {
catalog_entries.erase(table_name);
catalog_map->EraseEntry(table_name);
}

string GetDropSQL(CatalogType type, const string &table_name, bool cascade) {
Expand All @@ -199,7 +234,7 @@ string GetDropSQL(CatalogType type, const string &table_name, bool cascade) {
}

void SQLiteTransaction::DropEntry(CatalogType type, const string &table_name, bool cascade) {
catalog_entries.erase(table_name);
catalog_map->EraseEntry(table_name);
db->Execute(GetDropSQL(type, table_name, cascade));
}

Expand Down
25 changes: 25 additions & 0 deletions test/sql/storage/attach_sakila.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# name: test/sql/scanner/sakila.test
# description: Test sakila database
# group: [sqlite_scanner]

require sqlite_scanner

statement ok
ATTACH 'data/db/sakila.db' (READ_ONLY);

statement ok
USE sakila;

statement ok
SELECT columns.database_name, columns.schema_name, columns.table_name, list(
struct_pack(column_name, data_type, is_primary_key := c.column_index IS NOT NULL) order by column_index),
t.estimated_size AS estimated_size, t.table_oid AS table_oid
FROM duckdb_columns() columns
LEFT JOIN duckdb_tables() t USING (table_oid)
LEFT JOIN (
SELECT table_oid, UNNEST(constraint_column_indexes)+1 column_index
FROM duckdb_constraints()
WHERE constraint_type='PRIMARY KEY') c
USING (table_oid, column_index)
WHERE NOT columns.internal AND columns.table_name ILIKE '%%'
GROUP BY ALL;
Loading