Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/Client/BuzzHouse/Generator/SessionSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ std::unordered_map<String, CHSetting> serverSettings = {
{"create_index_ignore_unique", trueOrFalseSettingNoOracle},
{"create_table_empty_primary_key_by_default", trueOrFalseSettingNoOracle},
{"cross_to_inner_join_rewrite", CHSetting(zeroOneTwo, {"0", "1", "2"}, false)},
{"data_lake_delete_data_on_drop", trueOrFalseSettingNoOracle},
{"database_atomic_wait_for_drop_and_detach_synchronously", trueOrFalseSettingNoOracle},
{"database_datalake_require_metadata_access", trueOrFalseSettingNoOracle},
{"database_replicated_allow_explicit_uuid", CHSetting(zeroOneTwo, {}, false)},
Expand Down Expand Up @@ -873,7 +874,6 @@ std::unordered_map<String, CHSetting> serverSettings = {
[](RandomGenerator & rg, FuzzConfig &) { return std::to_string(rg.thresholdGenerator<uint64_t>(0.3, 0.2, 0, 10800)); },
{},
false)},
{"iceberg_delete_data_on_drop", trueOrFalseSettingNoOracle},
{"iceberg_expire_default_min_snapshots_to_keep",
CHSetting(
[](RandomGenerator & rg, FuzzConfig &) { return std::to_string(rg.thresholdGenerator<uint64_t>(0.2, 0.2, 0, 10)); }, {}, false)},
Expand Down
10 changes: 7 additions & 3 deletions src/Core/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5554,9 +5554,9 @@ Possible values:
- manifest_file_entry - Everything above + traversed avro manifest files entries.
)", 0) \
\
DECLARE(Bool, iceberg_delete_data_on_drop, false, R"(
Whether to delete all iceberg files on drop or not.
)", 0) \
DECLARE_WITH_ALIAS(Bool, data_lake_delete_data_on_drop, false, R"(
Whether to delete the underlying data files when dropping a data lake table. For catalog databases the catalog is asked to purge the data (`purgeRequested=true`); for self-managed tables ClickHouse removes the files directly.
)", 0, iceberg_delete_data_on_drop) \
DECLARE(Int64, iceberg_expire_default_min_snapshots_to_keep, 1, R"(
Default value for Iceberg table property `history.expire.min-snapshots-to-keep` used by `expire_snapshots` when that property is absent.
)", 0) \
Expand Down Expand Up @@ -7651,6 +7651,10 @@ Allow experimental database engine DataLakeCatalog with catalog_type = 'iceberg'

Cloud default value: `1`.
)", BETA, allow_database_iceberg) \
DECLARE(Bool, datalake_ignore_unsupported_table_properties, false, R"(
Allow `CREATE TABLE`, `CREATE TABLE ... AS`, and `SHOW CREATE TABLE` in a `DataLakeCatalog` database to omit unsupported table properties, including explicitly specified and inherited properties. Supported properties are preserved. By default, properties that cannot be represented cause an exception.
This setting does not suppress invalid expressions, unknown columns, invalid transform arguments, or incompatible storage engines, endpoints, and credentials.
)", BETA) \
DECLARE_WITH_ALIAS(Bool, allow_experimental_database_unity_catalog, true, R"(
Allow experimental database engine DataLakeCatalog with catalog_type = 'unity'

Expand Down
2 changes: 2 additions & 0 deletions src/Core/SettingsChangesHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const VersionToSettingsChangesMap & getSettingsChangesHistory()
addSettingsChanges(settings_changes_history, "26.6.2.20001.altinityantalya",
{
{"use_puffin_files_cache", false, true, "Enables cache of parsed Puffin file content such as deletion vectors."},
{"data_lake_delete_data_on_drop", false, false, "New setting that unifies dropping of data lake data; the released `iceberg_delete_data_on_drop` is kept as an alias for it."},
{"datalake_ignore_unsupported_table_properties", false, false, "New setting: allow `CREATE TABLE` and `SHOW CREATE TABLE` in a `DataLakeCatalog` to omit unsupported table properties."},
});

addSettingsChanges(settings_changes_history, "26.6",
Expand Down
87 changes: 87 additions & 0 deletions src/Databases/DataLake/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#include <Storages/ObjectStorage/DataLakes/Iceberg/SchemaProcessor.h>

#include <fmt/format.h>
#include <Poco/URI.h>

namespace DB::ErrorCodes
{
extern const int BAD_ARGUMENTS;
Expand Down Expand Up @@ -121,4 +124,88 @@ std::pair<std::string, std::string> parseTableName(const std::string & name)
return {namespace_name, table_name};
}

String constructTableLocation(
Comment thread
zvonand marked this conversation as resolved.
const String & location_scheme,
const String & storage_endpoint,
const String & namespace_name,
const String & table_name,
DB::S3UriStyle uri_style)
{
Poco::URI uri(storage_endpoint);
auto path = uri.getPath();
while (path.starts_with('/'))
path.erase(0, 1);
while (path.ends_with('/'))
path.pop_back();

if (location_scheme == "abfss")
{
/// Azure: `abfss://<container>@<host>/<path>`. `storage_endpoint` is
/// `https://<host>/<container>/<extra>` or `abfss://<container>@<host>/<extra>`
String container = uri.getUserInfo();
String account_host = uri.getHost();
String extra_path = path;

if (container.empty())
{
auto first_slash = extra_path.find('/');
if (first_slash == String::npos)
{
container = std::move(extra_path);
extra_path.clear();
}
else
{
container = extra_path.substr(0, first_slash);
extra_path = extra_path.substr(first_slash + 1);
}
}

if (account_host.empty() || container.empty())
throw DB::Exception(
DB::ErrorCodes::BAD_ARGUMENTS,
"`storage_endpoint` ({}) for Azure must include both account host and container "
"(expected https://<account>.dfs.core.windows.net/<container>[/<sub-path>] or "
"abfss://<container>@<account>.dfs.core.windows.net[/<sub-path>])",
storage_endpoint);

if (extra_path.empty())
return fmt::format("abfss://{}@{}/{}/{}", container, account_host, namespace_name, table_name);
return fmt::format("abfss://{}@{}/{}/{}/{}", container, account_host, extra_path, namespace_name, table_name);
}

if (location_scheme == "s3")
{
if (uri_style == DB::S3UriStyle::VIRTUAL_HOSTED)
throw DB::Exception(
DB::ErrorCodes::BAD_ARGUMENTS,
"CREATE TABLE with `storage_uri_style = 'virtual_hosted'` cannot derive the bucket from "
"`storage_endpoint` ({}); set `default_base_location` (a full s3://<bucket>/<prefix>) instead.",
storage_endpoint);

if (path.empty())
throw DB::Exception(
DB::ErrorCodes::BAD_ARGUMENTS,
"`storage_endpoint` ({}) does not contain a bucket; "
"CREATE TABLE in DataLakeCatalog requires `storage_endpoint` to include a non-empty bucket path.",
storage_endpoint);
return fmt::format("s3://{}/{}/{}", path, namespace_name, table_name);
}

String authority = uri.getAuthority();
if (authority.empty())
{
if (path.empty())
throw DB::Exception(
DB::ErrorCodes::BAD_ARGUMENTS,
"`storage_endpoint` ({}) does not contain a path",
storage_endpoint);
return fmt::format("{}:///{}/{}/{}", location_scheme, path, namespace_name, table_name);
}

if (path.empty())
return fmt::format("{}://{}/{}/{}", location_scheme, authority, namespace_name, table_name);
return fmt::format("{}://{}/{}/{}/{}", location_scheme, authority, path, namespace_name, table_name);
}

}
8 changes: 8 additions & 0 deletions src/Databases/DataLake/Common.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <Core/NamesAndTypes.h>
#include <Core/SettingsEnums.h>
#include <Core/Types.h>
#include <Interpreters/Context_fwd.h>

Expand All @@ -19,4 +20,11 @@ DB::DataTypePtr getType(const String & type_name, bool nullable, DB::ContextPtr
/// `E` is a table name.
std::pair<std::string, std::string> parseTableName(const std::string & name);

String constructTableLocation(
const String & location_scheme,
const String & storage_endpoint,
const String & namespace_name,
const String & table_name,
DB::S3UriStyle uri_style = DB::S3UriStyle::AUTO);

}
Loading
Loading