| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #pragma once |
| |
| /// \file iceberg/catalog/sql/sql_catalog.h |
| /// SQL catalog implementation. |
| /// |
| /// `SqlCatalog` implements the Iceberg `Catalog` API on top of a relational |
| /// database. Database access goes through the `CatalogStore` interface. |
| |
| #include <cstdint> |
| #include <memory> |
| #include <string> |
| #include <string_view> |
| #include <unordered_map> |
| #include <unordered_set> |
| #include <vector> |
| |
| #include "iceberg/catalog.h" |
| #include "iceberg/catalog/sql/catalog_store.h" |
| #include "iceberg/catalog/sql/iceberg_sql_catalog_export.h" |
| #include "iceberg/result.h" |
| #include "iceberg/table_identifier.h" |
| #include "iceberg/type_fwd.h" |
| |
| namespace iceberg::sql { |
| |
| /// \brief Default maximum number of database connections for built-in SQL stores. |
| constexpr static int32_t kMaxConnections = 10; |
| |
| /// \brief Configuration for the SQL catalog. |
| struct ICEBERG_SQL_CATALOG_EXPORT SqlCatalogConfig { |
| /// Logical catalog name. Scopes all rows via the `catalog_name` column so that |
| /// multiple catalogs can share one database. |
| std::string name = "sql_catalog"; |
| /// Database connection string interpreted by the chosen `CatalogStore`. |
| std::string uri; |
| /// Base location used to derive table locations when none is supplied. |
| std::string warehouse_location; |
| /// Maximum number of database connections. Built-in stores use a single |
| /// connection when this is 1 and a bounded sqlpp23 connection pool otherwise. |
| int32_t max_connections = kMaxConnections; |
| /// Additional connector-specific properties. |
| std::unordered_map<std::string, std::string> props; |
| }; |
| |
| /// \brief SQL-backed Iceberg catalog. |
| class ICEBERG_SQL_CATALOG_EXPORT SqlCatalog |
| : public Catalog, |
| public std::enable_shared_from_this<SqlCatalog> { |
| public: |
| ~SqlCatalog() override; |
| |
| SqlCatalog(const SqlCatalog&) = delete; |
| SqlCatalog& operator=(const SqlCatalog&) = delete; |
| SqlCatalog(SqlCatalog&&) = delete; |
| SqlCatalog& operator=(SqlCatalog&&) = delete; |
| |
| /// \brief Create a catalog backed by a user-supplied `CatalogStore`. |
| /// |
| /// This is the extension point for custom databases/drivers: implement |
| /// `CatalogStore` and pass it here. The catalog initializes its schema |
| /// (creating the backing tables if they do not exist) before returning. |
| /// |
| /// \param config Catalog configuration (name and warehouse location are used; |
| /// `uri` is informational because the store is already constructed). |
| /// \param file_io File IO used to read and write table metadata files. |
| /// \param store The catalog metadata store. Must not be null. |
| static Result<std::shared_ptr<SqlCatalog>> Make(const SqlCatalogConfig& config, |
| std::shared_ptr<FileIO> file_io, |
| std::shared_ptr<CatalogStore> store); |
| |
| std::string_view name() const override; |
| |
| Status CreateNamespace( |
| const Namespace& ns, |
| const std::unordered_map<std::string, std::string>& properties) override; |
| |
| Result<std::vector<Namespace>> ListNamespaces(const Namespace& ns) const override; |
| |
| Result<std::unordered_map<std::string, std::string>> GetNamespaceProperties( |
| const Namespace& ns) const override; |
| |
| Status DropNamespace(const Namespace& ns) override; |
| |
| Result<bool> NamespaceExists(const Namespace& ns) const override; |
| |
| Status UpdateNamespaceProperties( |
| const Namespace& ns, const std::unordered_map<std::string, std::string>& updates, |
| const std::unordered_set<std::string>& removals) override; |
| |
| Result<std::vector<TableIdentifier>> ListTables(const Namespace& ns) const override; |
| |
| Result<std::shared_ptr<Table>> CreateTable( |
| const TableIdentifier& identifier, const std::shared_ptr<Schema>& schema, |
| const std::shared_ptr<PartitionSpec>& spec, const std::shared_ptr<SortOrder>& order, |
| const std::string& location, |
| const std::unordered_map<std::string, std::string>& properties) override; |
| |
| Result<std::shared_ptr<Table>> UpdateTable( |
| const TableIdentifier& identifier, |
| const std::vector<std::unique_ptr<TableRequirement>>& requirements, |
| const std::vector<std::unique_ptr<TableUpdate>>& updates) override; |
| |
| Result<std::shared_ptr<Transaction>> StageCreateTable( |
| const TableIdentifier& identifier, const std::shared_ptr<Schema>& schema, |
| const std::shared_ptr<PartitionSpec>& spec, const std::shared_ptr<SortOrder>& order, |
| const std::string& location, |
| const std::unordered_map<std::string, std::string>& properties) override; |
| |
| Result<bool> TableExists(const TableIdentifier& identifier) const override; |
| |
| /// \brief Drop a table. |
| /// |
| /// SqlCatalog currently removes only the catalog entry. Support for deleting |
| /// table data and metadata files when `purge` is true is not implemented yet. |
| Status DropTable(const TableIdentifier& identifier, bool purge) override; |
| |
| Status RenameTable(const TableIdentifier& from, const TableIdentifier& to) override; |
| |
| Result<std::shared_ptr<Table>> LoadTable(const TableIdentifier& identifier) override; |
| |
| Result<std::shared_ptr<Table>> RegisterTable( |
| const TableIdentifier& identifier, |
| const std::string& metadata_file_location) override; |
| |
| /// \brief Create a catalog backed by the built-in SQLite client. |
| /// |
| /// \param config `uri` is the SQLite database file path (or ":memory:"). |
| /// \param file_io File IO used to read and write table metadata files. |
| /// \return A catalog instance, or ErrorKind::kNotSupported if the SQLite |
| /// connector was not built. |
| static Result<std::shared_ptr<SqlCatalog>> MakeSqliteCatalog( |
| const SqlCatalogConfig& config, std::shared_ptr<FileIO> file_io); |
| |
| /// \brief Create a catalog backed by the built-in PostgreSQL (libpq) client. |
| /// |
| /// \param config `uri` is parsed as |
| /// `[scheme://][user[:password]@]host[:port][/database]`. |
| /// \param file_io File IO used to read and write table metadata files. |
| /// \return A catalog instance, or ErrorKind::kNotSupported if the PostgreSQL |
| /// connector was not built. |
| static Result<std::shared_ptr<SqlCatalog>> MakePostgreSqlCatalog( |
| const SqlCatalogConfig& config, std::shared_ptr<FileIO> file_io); |
| |
| /// \brief Create a catalog backed by the built-in MySQL client. |
| /// |
| /// \param config `uri` is parsed as |
| /// `[scheme://][user[:password]@]host[:port][/database]`. |
| /// \param file_io File IO used to read and write table metadata files. |
| /// \return A catalog instance, or ErrorKind::kNotSupported if the MySQL |
| /// connector was not built. |
| static Result<std::shared_ptr<SqlCatalog>> MakeMySqlCatalog( |
| const SqlCatalogConfig& config, std::shared_ptr<FileIO> file_io); |
| |
| private: |
| SqlCatalog(SqlCatalogConfig config, std::shared_ptr<FileIO> file_io, |
| std::shared_ptr<CatalogStore> store); |
| |
| /// \brief Resolve the current metadata location for a table, or NoSuchTable. |
| Result<std::string> GetTableMetadataLocation(const TableIdentifier& identifier) const; |
| |
| /// \brief Build a Table object from a metadata location. |
| Result<std::shared_ptr<Table>> LoadTableFrom(const TableIdentifier& identifier, |
| const std::string& metadata_location); |
| |
| SqlCatalogConfig config_; |
| std::shared_ptr<FileIO> file_io_; |
| std::shared_ptr<CatalogStore> store_; |
| }; |
| |
| } // namespace iceberg::sql |