diff --git a/Makefile b/Makefile index 44b85934..6815805f 100644 --- a/Makefile +++ b/Makefile @@ -19,12 +19,16 @@ SRCS = src/scan/heap_reader.cpp \ src/pgduckdb_options.cpp \ src/pgduckdb_planner.cpp \ src/pgduckdb_types.cpp \ - src/pgduckdb.cpp + src/pgduckdb.cpp \ + src/catalog/pgduckdb_storage.cpp \ + src/catalog/pgduckdb_schema.cpp \ + src/catalog/pgduckdb_table.cpp \ + src/catalog/pgduckdb_catalog.cpp OBJS = $(subst .cpp,.o, $(SRCS)) -DUCKDB_BUILD_CXX_FLAGS= -DUCKDB_BUILD_TYPE= +DUCKDB_BUILD_CXX_FLAGS:= +DUCKDB_BUILD_TYPE:= ifeq ($(DUCKDB_BUILD), Debug) DUCKDB_BUILD_CXX_FLAGS = -g -O0 diff --git a/include/pgduckdb/catalog/pgduckdb_catalog.hpp b/include/pgduckdb/catalog/pgduckdb_catalog.hpp new file mode 100644 index 00000000..43525a22 --- /dev/null +++ b/include/pgduckdb/catalog/pgduckdb_catalog.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include "duckdb/storage/storage_extension.hpp" +#include "duckdb/catalog/catalog.hpp" +#include "pgduckdb/catalog/pgduckdb_schema.hpp" + +extern "C" { +#include "postgres.h" +#include "miscadmin.h" +#include "utils/snapshot.h" +} + +namespace pgduckdb { + +using duckdb::optional_ptr; +using duckdb::case_insensitive_map_t; +using duckdb::unique_ptr; +using duckdb::string; +using duckdb::CatalogEntry; +using duckdb::TableCatalogEntry; +using duckdb::SchemaCatalogEntry; +using duckdb::Catalog; +using duckdb::AttachedDatabase; +using duckdb::AccessMode; +using duckdb::AttachInfo; +using duckdb::StorageExtensionInfo; +using duckdb::ClientContext; +using duckdb::CreateSchemaInfo; +using duckdb::CatalogTransaction; +using duckdb::PhysicalOperator; +using duckdb::LogicalOperator; +using duckdb::CreateStatement; +using duckdb::LogicalInsert; +using duckdb::LogicalDelete; +using duckdb::LogicalUpdate; +using duckdb::LogicalCreateTable; +using duckdb::OnEntryNotFound; +using duckdb::QueryErrorContext; +using duckdb::Binder; +using duckdb::DropInfo; +using duckdb::DatabaseSize; + +class PostgresCatalog : public Catalog { +public: + PostgresCatalog(AttachedDatabase &db, const string &connection_string, AccessMode access_mode); +public: + static unique_ptr Attach(StorageExtensionInfo *storage_info, ClientContext &context, AttachedDatabase &db, const string &name, AttachInfo &info, AccessMode access_mode); +public: + string path; + AccessMode access_mode; +public: + // -- Catalog API -- + void Initialize(bool load_builtin) override; + string GetCatalogType() override; + optional_ptr CreateSchema(CatalogTransaction transaction, CreateSchemaInfo &info) override; + optional_ptr GetSchema(CatalogTransaction transaction, const string &schema_name, OnEntryNotFound if_not_found, QueryErrorContext error_context = QueryErrorContext()) override; + void ScanSchemas(ClientContext &context, std::function callback) override; + unique_ptr PlanCreateTableAs(ClientContext &context, LogicalCreateTable &op, unique_ptr plan) override; + unique_ptr PlanInsert(ClientContext &context, LogicalInsert &op, unique_ptr plan) override; + unique_ptr PlanDelete(ClientContext &context, LogicalDelete &op, unique_ptr plan) override; + unique_ptr PlanUpdate(ClientContext &context, LogicalUpdate &op, unique_ptr plan) override; + unique_ptr BindCreateIndex(Binder &binder, CreateStatement &stmt, TableCatalogEntry &table, unique_ptr plan) override; + DatabaseSize GetDatabaseSize(ClientContext &context) override; + bool InMemory() override; + string GetDBPath() override; + void DropSchema(ClientContext &context, DropInfo &info) override; +private: + case_insensitive_map_t> schemas; + Snapshot snapshot; +}; + +} // namespace pgduckdb diff --git a/include/pgduckdb/catalog/pgduckdb_schema.hpp b/include/pgduckdb/catalog/pgduckdb_schema.hpp new file mode 100644 index 00000000..ddb13933 --- /dev/null +++ b/include/pgduckdb/catalog/pgduckdb_schema.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp" +#include "pgduckdb/catalog/pgduckdb_table.hpp" + +extern "C" { +#include "postgres.h" +#include "miscadmin.h" +#include "utils/snapshot.h" +} + +namespace pgduckdb { + +using duckdb::optional_ptr; +using duckdb::unique_ptr; +using duckdb::string; +using duckdb::case_insensitive_map_t; +using duckdb::CatalogType; +using duckdb::CatalogEntry; +using duckdb::TableCatalogEntry; +using duckdb::SchemaCatalogEntry; +using duckdb::Catalog; +using duckdb::AttachedDatabase; +using duckdb::AccessMode; +using duckdb::AlterInfo; +using duckdb::ClientContext; +using duckdb::CreateSchemaInfo; +using duckdb::CreateTableFunctionInfo; +using duckdb::CreateSequenceInfo; +using duckdb::CreateViewInfo; +using duckdb::CreateFunctionInfo; +using duckdb::CreateTypeInfo; +using duckdb::CreateIndexInfo; +using duckdb::CreateCollationInfo; +using duckdb::CreateCopyFunctionInfo; +using duckdb::CreatePragmaFunctionInfo; +using duckdb::BoundCreateTableInfo; +using duckdb::CatalogTransaction; +using duckdb::DropInfo; + +class PostgresSchema : public SchemaCatalogEntry { +public: + PostgresSchema(Catalog &catalog, CreateSchemaInfo &info, Snapshot snapshot); +public: + // -- Schema API -- + void Scan(ClientContext &context, CatalogType type, const std::function &callback) override; + void Scan(CatalogType type, const std::function &callback) override; + optional_ptr CreateIndex(CatalogTransaction transaction, CreateIndexInfo &info, TableCatalogEntry &table) override; + optional_ptr CreateFunction(CatalogTransaction transaction, CreateFunctionInfo &info) override; + optional_ptr CreateTable(CatalogTransaction transaction, BoundCreateTableInfo &info) override; + optional_ptr CreateView(CatalogTransaction transaction, CreateViewInfo &info) override; + optional_ptr CreateSequence(CatalogTransaction transaction, CreateSequenceInfo &info) override; + optional_ptr CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo &info) override; + optional_ptr CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo &info) override; + optional_ptr CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo &info) override; + optional_ptr CreateCollation(CatalogTransaction transaction, CreateCollationInfo &info) override; + optional_ptr CreateType(CatalogTransaction transaction, CreateTypeInfo &info) override; + optional_ptr GetEntry(CatalogTransaction transaction, CatalogType type, const string &name) override; + void DropEntry(ClientContext &context, DropInfo &info) override; + void Alter(CatalogTransaction transaction, AlterInfo &info) override; +private: + case_insensitive_map_t> tables; + Snapshot snapshot; + Catalog &catalog; +}; + +} // namespace pgduckdb diff --git a/include/pgduckdb/catalog/pgduckdb_storage.hpp b/include/pgduckdb/catalog/pgduckdb_storage.hpp new file mode 100644 index 00000000..e5b68c65 --- /dev/null +++ b/include/pgduckdb/catalog/pgduckdb_storage.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "duckdb/storage/storage_extension.hpp" +extern "C" { +#include "postgres.h" +#include "miscadmin.h" +#include "utils/snapshot.h" +} + +namespace pgduckdb { + +class PostgresStorageExtensionInfo : public duckdb::StorageExtensionInfo { +public: + PostgresStorageExtensionInfo(Snapshot snapshot) : snapshot(snapshot) {} +public: + Snapshot snapshot; +}; + +class PostgresStorageExtension : public duckdb::StorageExtension { +public: + PostgresStorageExtension(Snapshot snapshot); +}; + +} // namespace pgduckdb diff --git a/include/pgduckdb/catalog/pgduckdb_table.hpp b/include/pgduckdb/catalog/pgduckdb_table.hpp new file mode 100644 index 00000000..62108a7b --- /dev/null +++ b/include/pgduckdb/catalog/pgduckdb_table.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" +#include "duckdb/storage/table_storage_info.hpp" + +extern "C" { +#include "postgres.h" +#include "utils/snapshot.h" +} + +namespace pgduckdb { + +using duckdb::optional_ptr; +using duckdb::unique_ptr; +using duckdb::string; +using duckdb::CatalogType; +using duckdb::CatalogEntry; +using duckdb::TableCatalogEntry; +using duckdb::SchemaCatalogEntry; +using duckdb::Catalog; +using duckdb::ClientContext; +using duckdb::TableStorageInfo; +using duckdb::FunctionData; +using duckdb::TableFunction; +using duckdb::column_t; +using duckdb::CreateTableInfo; +using duckdb::BaseStatistics; + +class PostgresTable : public TableCatalogEntry { +public: + PostgresTable(Catalog &catalog, SchemaCatalogEntry &schema, CreateTableInfo &info, Oid oid, Snapshot snapshot); +public: + static bool PopulateColumns(CreateTableInfo &info, Oid relid, Snapshot snapshot); +public: + // -- Table API -- + unique_ptr GetStatistics(ClientContext &context, column_t column_id) override; + TableFunction GetScanFunction(ClientContext &context, unique_ptr &bind_data) override; + TableStorageInfo GetStorageInfo(ClientContext &context) override; +private: + Oid oid; + Snapshot snapshot; +}; + +} // namespace pgduckdb diff --git a/src/catalog/pgduckdb_catalog.cpp b/src/catalog/pgduckdb_catalog.cpp new file mode 100644 index 00000000..761682a9 --- /dev/null +++ b/src/catalog/pgduckdb_catalog.cpp @@ -0,0 +1,135 @@ +#include "pgduckdb/catalog/pgduckdb_catalog.hpp" +#include "duckdb/parser/parsed_data/attach_info.hpp" +#include "duckdb/parser/parsed_data/create_schema_info.hpp" + +extern "C" { +#include "postgres.h" +#include "fmgr.h" +#include "catalog/pg_namespace.h" +#include "utils/syscache.h" +#include "utils/builtins.h" +#include "utils/rel.h" +#include "utils/snapshot.h" +#include "access/heapam.h" +#include "access/htup_details.h" +#include "catalog/indexing.h" +#include "access/genam.h" +#include "access/xact.h" +} + +namespace pgduckdb { + +PostgresCatalog::PostgresCatalog(duckdb::AttachedDatabase &db, const duckdb::string &connection_string, duckdb::AccessMode access_mode) + : duckdb::Catalog(db), path(connection_string), access_mode(access_mode) { +} + +duckdb::unique_ptr PostgresCatalog::Attach(duckdb::StorageExtensionInfo *storage_info, duckdb::ClientContext &context, duckdb::AttachedDatabase &db, const duckdb::string &name, duckdb::AttachInfo &info, duckdb::AccessMode access_mode) { + duckdb::string connection_string = info.path; + + if (!storage_info) { + throw duckdb::InternalException("PostgresCatalog should always have access to the PostgresStorageExtensionInfo"); + } + return duckdb::make_uniq(db, connection_string, access_mode); +} + +// ------------------ Catalog API --------------------- + +void PostgresCatalog::Initialize(bool load_builtin) { + return; +} + +string PostgresCatalog::GetCatalogType() { + return "pgduckdb"; +} + +optional_ptr PostgresCatalog::CreateSchema(CatalogTransaction transaction, CreateSchemaInfo &info) { + throw duckdb::NotImplementedException("CreateSchema not supported yet"); +} + +static Oid LookupSchema(const string &schema_name, Snapshot snapshot) { + auto rel = table_open(NamespaceRelationId, AccessShareLock); + + ScanKeyData key; + ScanKeyInit(&key, + Anum_pg_namespace_nspname, + BTEqualStrategyNumber, + NAMEOID, + CStringGetDatum(schema_name.c_str())); + + auto scan = systable_beginscan(rel, NamespaceNameIndexId, true, snapshot, 1, &key); + + auto tuple = systable_getnext(scan); + Oid nspoid = InvalidOid; + if (HeapTupleIsValid(tuple)) { + nspoid = ((Form_pg_namespace) GETSTRUCT(tuple))->oid; + } + + systable_endscan(scan); + table_close(rel, AccessShareLock); + + return nspoid; +} + +optional_ptr PostgresCatalog::GetSchema(CatalogTransaction transaction, const string &schema_name, OnEntryNotFound if_not_found, QueryErrorContext error_context) { + if (schema_name == DEFAULT_SCHEMA) { + return GetSchema(transaction, "public", if_not_found, error_context); + } + + auto it = schemas.find(schema_name); + if (it != schemas.end()) { + return it->second.get(); + } + + auto oid = LookupSchema(schema_name, snapshot); + if (!OidIsValid(oid)) { + // Schema could not be found + return nullptr; + } + + CreateSchemaInfo create_schema; + create_schema.schema = schema_name; + schemas[schema_name] = duckdb::make_uniq(*this, create_schema, snapshot); + return schemas[schema_name].get(); +} + +void PostgresCatalog::ScanSchemas(ClientContext &context, std::function callback) { + throw duckdb::NotImplementedException("ScanSchemas not supported yet"); +} + +unique_ptr PostgresCatalog::PlanCreateTableAs(ClientContext &context, LogicalCreateTable &op, unique_ptr plan) { + throw duckdb::NotImplementedException("PlanCreateTableAs not supported yet"); +} + +unique_ptr PostgresCatalog::PlanInsert(ClientContext &context, LogicalInsert &op, unique_ptr plan) { + throw duckdb::NotImplementedException("PlanInsert not supported yet"); +} + +unique_ptr PostgresCatalog::PlanDelete(ClientContext &context, LogicalDelete &op, unique_ptr plan) { + throw duckdb::NotImplementedException("PlanDelete not supported yet"); +} + +unique_ptr PostgresCatalog::PlanUpdate(ClientContext &context, LogicalUpdate &op, unique_ptr plan) { + throw duckdb::NotImplementedException("PlanUpdate not supported yet"); +} + +unique_ptr PostgresCatalog::BindCreateIndex(Binder &binder, CreateStatement &stmt, TableCatalogEntry &table, unique_ptr plan) { + throw duckdb::NotImplementedException("BindCreateIndex not supported yet"); +} + +DatabaseSize PostgresCatalog::GetDatabaseSize(ClientContext &context) { + throw duckdb::NotImplementedException("GetDatabaseSize not supported yet"); +} + +bool PostgresCatalog::InMemory() { + return false; +} + +string PostgresCatalog::GetDBPath() { + return path; +} + +void PostgresCatalog::DropSchema(ClientContext &context, DropInfo &info) { + throw duckdb::NotImplementedException("DropSchema not supported yet"); +} + +} // namespace pgduckdb diff --git a/src/catalog/pgduckdb_schema.cpp b/src/catalog/pgduckdb_schema.cpp new file mode 100644 index 00000000..b073ed0e --- /dev/null +++ b/src/catalog/pgduckdb_schema.cpp @@ -0,0 +1,103 @@ +#include "pgduckdb/catalog/pgduckdb_schema.hpp" +#include "pgduckdb/catalog/pgduckdb_table.hpp" +#include "duckdb/parser/parsed_data/create_table_info.hpp" + +extern "C" { +#include "postgres.h" +#include "catalog/namespace.h" +#include "catalog/pg_class.h" +#include "optimizer/planmain.h" +#include "optimizer/planner.h" +#include "utils/builtins.h" +#include "utils/regproc.h" +#include "utils/snapmgr.h" +#include "utils/syscache.h" +} + +namespace pgduckdb { + +PostgresSchema::PostgresSchema(Catalog &catalog, CreateSchemaInfo &info, Snapshot snapshot) : SchemaCatalogEntry(catalog, info), snapshot(snapshot), catalog(catalog) {} + +void PostgresSchema::Scan(ClientContext &context, CatalogType type, const std::function &callback) { + throw duckdb::NotImplementedException("Scan(with context) not supported yet"); +} + +void PostgresSchema::Scan(CatalogType type, const std::function &callback) { + throw duckdb::NotImplementedException("Scan(no context) not supported yet"); +} + +optional_ptr PostgresSchema::CreateIndex(CatalogTransaction transaction, CreateIndexInfo &info, TableCatalogEntry &table) { + throw duckdb::NotImplementedException("CreateIndex not supported yet"); +} + +optional_ptr PostgresSchema::CreateFunction(CatalogTransaction transaction, CreateFunctionInfo &info) { + throw duckdb::NotImplementedException("CreateFunction not supported yet"); +} + +optional_ptr PostgresSchema::CreateTable(CatalogTransaction transaction, BoundCreateTableInfo &info) { + throw duckdb::NotImplementedException("CreateTable not supported yet"); +} + +optional_ptr PostgresSchema::CreateView(CatalogTransaction transaction, CreateViewInfo &info) { + throw duckdb::NotImplementedException("CreateView not supported yet"); +} + +optional_ptr PostgresSchema::CreateSequence(CatalogTransaction transaction, CreateSequenceInfo &info) { + throw duckdb::NotImplementedException("CreateSequence not supported yet"); +} + +optional_ptr PostgresSchema::CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo &info) { + throw duckdb::NotImplementedException("CreateTableFunction not supported yet"); +} + +optional_ptr PostgresSchema::CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo &info) { + throw duckdb::NotImplementedException("CreateCopyFunction not supported yet"); +} + +optional_ptr PostgresSchema::CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo &info) { + throw duckdb::NotImplementedException("CreatePragmaFunction not supported yet"); +} + +optional_ptr PostgresSchema::CreateCollation(CatalogTransaction transaction, CreateCollationInfo &info) { + throw duckdb::NotImplementedException("CreateCollation not supported yet"); +} + +optional_ptr PostgresSchema::CreateType(CatalogTransaction transaction, CreateTypeInfo &info) { + throw duckdb::NotImplementedException("CreateType not supported yet"); +} + +optional_ptr PostgresSchema::GetEntry(CatalogTransaction transaction, CatalogType type, const string &name) { + if (type != CatalogType::TABLE_ENTRY) { + throw duckdb::NotImplementedException("GetEntry (type: %s) not supported yet", duckdb::EnumUtil::ToString(type)); + } + + auto it = tables.find(name); + if (it != tables.end()) { + return it->second.get(); + } + + RangeVar *table_range_var = makeRangeVarFromNameList(stringToQualifiedNameList(name.c_str(), NULL)); + Oid rel_oid = RangeVarGetRelid(table_range_var, AccessShareLock, true); + if (rel_oid == InvalidOid) { + // Table could not be found + return nullptr; + } + + CreateTableInfo info; + info.table = name; + if (!PostgresTable::PopulateColumns(info, rel_oid, snapshot)) { + return nullptr; + } + tables[name] = duckdb::make_uniq(catalog, *this, info, rel_oid, snapshot); + return tables[name].get(); +} + +void PostgresSchema::DropEntry(ClientContext &context, DropInfo &info) { + throw duckdb::NotImplementedException("DropEntry not supported yet"); +} + +void PostgresSchema::Alter(CatalogTransaction transaction, AlterInfo &info) { + throw duckdb::NotImplementedException("Alter not supported yet"); +} + +} // namespace pgduckdb diff --git a/src/catalog/pgduckdb_storage.cpp b/src/catalog/pgduckdb_storage.cpp new file mode 100644 index 00000000..410d7795 --- /dev/null +++ b/src/catalog/pgduckdb_storage.cpp @@ -0,0 +1,11 @@ +#include "pgduckdb/catalog/pgduckdb_storage.hpp" +#include "pgduckdb/catalog/pgduckdb_catalog.hpp" + +namespace pgduckdb { + +PostgresStorageExtension::PostgresStorageExtension(Snapshot snapshot) { + attach = PostgresCatalog::Attach; + storage_info = duckdb::make_uniq(snapshot); +} + +} // namespace pgduckdb diff --git a/src/catalog/pgduckdb_table.cpp b/src/catalog/pgduckdb_table.cpp new file mode 100644 index 00000000..14b3fd1c --- /dev/null +++ b/src/catalog/pgduckdb_table.cpp @@ -0,0 +1,56 @@ +#include "pgduckdb/pgduckdb_types.hpp" +#include "pgduckdb/catalog/pgduckdb_schema.hpp" +#include "pgduckdb/catalog/pgduckdb_table.hpp" +#include "duckdb/parser/parsed_data/create_table_info.hpp" +#include "pgduckdb/scan/postgres_seq_scan.hpp" + +extern "C" { +#include "postgres.h" +#include "access/tableam.h" +#include "access/heapam.h" +#include "storage/bufmgr.h" +} + +namespace pgduckdb { + +PostgresTable::PostgresTable(Catalog &catalog, SchemaCatalogEntry &schema, CreateTableInfo &info, Oid oid, Snapshot snapshot) : TableCatalogEntry(catalog, schema, info), oid(oid), snapshot(snapshot) {} + +bool PostgresTable::PopulateColumns(CreateTableInfo &info, Oid relid, Snapshot snapshot) { + auto rel = RelationIdGetRelation(relid); + auto tupleDesc = RelationGetDescr(rel); + + if (!tupleDesc) { + elog(ERROR, "Failed to get tuple descriptor for relation with OID %u", relid); + RelationClose(rel); + return false; + } + + for (int i = 0; i < tupleDesc->natts; i++) { + Form_pg_attribute attr = &tupleDesc->attrs[i]; + auto col_name = duckdb::string(NameStr(attr->attname)); + auto duck_type = ConvertPostgresToDuckColumnType(attr); + info.columns.AddColumn(duckdb::ColumnDefinition(col_name, duck_type)); + /* Log column name and type */ + elog(DEBUG3, "-- (DuckDB/PostgresHeapBind) Column name: %s, Type: %s --", col_name.c_str(), + duck_type.ToString().c_str()); + } + + RelationClose(rel); + return true; +} + +unique_ptr PostgresTable::GetStatistics(ClientContext &context, column_t column_id) { + throw duckdb::NotImplementedException("GetStatistics not supported yet"); +} + +TableFunction PostgresTable::GetScanFunction(ClientContext &context, unique_ptr &bind_data) { + // TODO: add cardinality + bind_data = duckdb::make_uniq(0, oid, snapshot); + return PostgresSeqScanFunction(); +} + +TableStorageInfo PostgresTable::GetStorageInfo(ClientContext &context) { + throw duckdb::NotImplementedException("GetStorageInfo not supported yet"); +} + +} // namespace pgduckdb diff --git a/src/pgduckdb_duckdb.cpp b/src/pgduckdb_duckdb.cpp index bf8d5f4d..99286bc1 100644 --- a/src/pgduckdb_duckdb.cpp +++ b/src/pgduckdb_duckdb.cpp @@ -1,6 +1,8 @@ #include "duckdb.hpp" #include "duckdb/parser/parsed_data/create_table_function_info.hpp" #include "duckdb/main/extension_util.hpp" +#include "duckdb/main/client_data.hpp" +#include "duckdb/catalog/catalog_search_path.hpp" #include "pgduckdb/pgduckdb_options.hpp" #include "pgduckdb/pgduckdb_duckdb.hpp" @@ -8,6 +10,7 @@ #include "pgduckdb/scan/postgres_index_scan.hpp" #include "pgduckdb/scan/postgres_seq_scan.hpp" #include "pgduckdb/pgduckdb_utils.hpp" +#include "pgduckdb/catalog/pgduckdb_storage.hpp" #include @@ -67,6 +70,7 @@ duckdb::unique_ptr DuckdbOpenDatabase() { duckdb::DBConfig config; config.SetOptionByName("extension_directory", duckdbGetExtensionDirectory()); + config.storage_extensions["pgduckdb"] = duckdb::make_uniq(GetActiveSnapshot()); return duckdb::make_uniq(nullptr, &config); } @@ -75,15 +79,17 @@ DuckdbCreateConnection(List *rtables, PlannerInfo *plannerInfo, List *neededColu auto db = DuckdbOpenDatabase(); /* Add tables */ - db->instance->config.replacement_scans.emplace_back( - pgduckdb::PostgresReplacementScan, - duckdb::make_uniq_base(rtables, plannerInfo, - neededColumns, query)); + //db->instance->config.replacement_scans.emplace_back( + // pgduckdb::PostgresReplacementScan, + // duckdb::make_uniq_base(rtables, plannerInfo, + // neededColumns, query)); + + auto &config = duckdb::DBConfig::GetConfig(*db->instance); auto connection = duckdb::make_uniq(*db); - // Add the postgres_scan inserted by the replacement scan auto &context = *connection->context; + auto &client_data = duckdb::ClientData::Get(context); pgduckdb::PostgresSeqScanFunction seq_scan_fun; duckdb::CreateTableFunctionInfo seq_scan_info(seq_scan_fun); @@ -93,6 +99,9 @@ DuckdbCreateConnection(List *rtables, PlannerInfo *plannerInfo, List *neededColu auto &catalog = duckdb::Catalog::GetSystemCatalog(context); context.transaction.BeginTransaction(); + + // Make sure the custom postgres catalog is used + client_data.catalog_search_path->Set({duckdb::CatalogSearchEntry("", "pgduckdb")}, duckdb::CatalogSetPathType::SET_SCHEMA); auto &instance = *db->instance; duckdb::ExtensionUtil::RegisterType(instance, "UnsupportedPostgresType", duckdb::LogicalTypeId::VARCHAR); catalog.CreateTableFunction(context, &seq_scan_info);