Skip to content

Commit 91e6a82

Browse files
authored
Merge pull request #1103 from Altinity/feature/antalya-25.8/timezone_for_iceberg_timestamptz
Timezone for iceberg timestamptz
2 parents a4abf75 + 42aa0be commit 91e6a82

File tree

20 files changed

+214
-66
lines changed

20 files changed

+214
-66
lines changed

src/Core/Settings.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6873,6 +6873,16 @@ Use roaring bitmap for iceberg positional deletes.
68736873
)", 0) \
68746874
DECLARE(Bool, export_merge_tree_part_overwrite_file_if_exists, false, R"(
68756875
Overwrite file if it already exists when exporting a merge tree part
6876+
)", 0) \
6877+
DECLARE(Timezone, iceberg_timezone_for_timestamptz, "UTC", R"(
6878+
Timezone for Iceberg timestamptz field.
6879+
6880+
Possible values:
6881+
6882+
- Any valid timezone, e.g. `Europe/Berlin`, `UTC` or `Zulu`
6883+
- `` (empty value) - use session timezone
6884+
6885+
Default value is `UTC`.
68766886
)", 0) \
68776887
\
68786888
/* ####################################################### */ \

src/Core/SettingsChangesHistory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const VersionToSettingsChangesMap & getSettingsChangesHistory()
4747
{"allow_retries_in_cluster_requests", false, false, "New setting"},
4848
{"object_storage_remote_initiator", false, false, "New setting."},
4949
{"allow_experimental_export_merge_tree_part", false, true, "Turned ON by default for Antalya."},
50+
{"iceberg_timezone_for_timestamptz", "UTC", "UTC", "New setting."}
5051
});
5152
addSettingsChanges(settings_changes_history, "25.8",
5253
{

src/Databases/DataLake/Common.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ std::vector<String> splitTypeArguments(const String & type_str)
6161
return args;
6262
}
6363

64-
DB::DataTypePtr getType(const String & type_name, bool nullable, const String & prefix)
64+
DB::DataTypePtr getType(const String & type_name, bool nullable, DB::ContextPtr context, const String & prefix)
6565
{
6666
String name = trim(type_name);
6767

6868
if (name.starts_with("array<") && name.ends_with(">"))
6969
{
7070
String inner = name.substr(6, name.size() - 7);
71-
return std::make_shared<DB::DataTypeArray>(getType(inner, nullable));
71+
return std::make_shared<DB::DataTypeArray>(getType(inner, nullable, context));
7272
}
7373

7474
if (name.starts_with("map<") && name.ends_with(">"))
@@ -79,7 +79,7 @@ DB::DataTypePtr getType(const String & type_name, bool nullable, const String &
7979
if (args.size() != 2)
8080
throw DB::Exception(DB::ErrorCodes::DATALAKE_DATABASE_ERROR, "Invalid data type {}", type_name);
8181

82-
return std::make_shared<DB::DataTypeMap>(getType(args[0], false), getType(args[1], nullable));
82+
return std::make_shared<DB::DataTypeMap>(getType(args[0], false, context), getType(args[1], nullable, context));
8383
}
8484

8585
if (name.starts_with("struct<") && name.ends_with(">"))
@@ -101,13 +101,13 @@ DB::DataTypePtr getType(const String & type_name, bool nullable, const String &
101101
String full_field_name = prefix.empty() ? field_name : prefix + "." + field_name;
102102

103103
field_names.push_back(full_field_name);
104-
field_types.push_back(getType(field_type, nullable, full_field_name));
104+
field_types.push_back(getType(field_type, nullable, context, full_field_name));
105105
}
106106
return std::make_shared<DB::DataTypeTuple>(field_types, field_names);
107107
}
108108

109-
return nullable ? DB::makeNullable(DB::Iceberg::IcebergSchemaProcessor::getSimpleType(name))
110-
: DB::Iceberg::IcebergSchemaProcessor::getSimpleType(name);
109+
return nullable ? DB::makeNullable(DB::Iceberg::IcebergSchemaProcessor::getSimpleType(name, context))
110+
: DB::Iceberg::IcebergSchemaProcessor::getSimpleType(name, context);
111111
}
112112

113113
std::pair<std::string, std::string> parseTableName(const std::string & name)

src/Databases/DataLake/Common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <Core/NamesAndTypes.h>
44
#include <Core/Types.h>
5+
#include <Interpreters/Context_fwd.h>
56

67
namespace DataLake
78
{
@@ -10,7 +11,7 @@ String trim(const String & str);
1011

1112
std::vector<String> splitTypeArguments(const String & type_str);
1213

13-
DB::DataTypePtr getType(const String & type_name, bool nullable, const String & prefix = "");
14+
DB::DataTypePtr getType(const String & type_name, bool nullable, DB::ContextPtr context, const String & prefix = "");
1415

1516
/// Parse a string, containing at least one dot, into a two substrings:
1617
/// A.B.C.D.E -> A.B.C.D and E, where

src/Databases/DataLake/DatabaseDataLake.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ StoragePtr DatabaseDataLake::tryGetTableImpl(const String & name, ContextPtr con
326326

327327
auto [namespace_name, table_name] = DataLake::parseTableName(name);
328328

329-
if (!catalog->tryGetTableMetadata(namespace_name, table_name, table_metadata))
329+
if (!catalog->tryGetTableMetadata(namespace_name, table_name, context_, table_metadata))
330330
return nullptr;
331331

332332
if (ignore_if_not_iceberg && !table_metadata.isDefaultReadableTable())
@@ -632,15 +632,15 @@ ASTPtr DatabaseDataLake::getCreateDatabaseQuery() const
632632

633633
ASTPtr DatabaseDataLake::getCreateTableQueryImpl(
634634
const String & name,
635-
ContextPtr /* context_ */,
635+
ContextPtr context_,
636636
bool /* throw_on_error */) const
637637
{
638638
auto catalog = getCatalog();
639639
auto table_metadata = DataLake::TableMetadata().withLocation().withSchema();
640640

641641
const auto [namespace_name, table_name] = DataLake::parseTableName(name);
642642

643-
if (!catalog->tryGetTableMetadata(namespace_name, table_name, table_metadata))
643+
if (!catalog->tryGetTableMetadata(namespace_name, table_name, context_, table_metadata))
644644
{
645645
throw Exception(
646646
ErrorCodes::CANNOT_GET_CREATE_TABLE_QUERY, "Table `{}` doesn't exist", name);

src/Databases/DataLake/GlueCatalog.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ bool GlueCatalog::existsTable(const std::string & database_name, const std::stri
276276
bool GlueCatalog::tryGetTableMetadata(
277277
const std::string & database_name,
278278
const std::string & table_name,
279+
DB::ContextPtr /* context_ */,
279280
TableMetadata & result) const
280281
{
281282
Aws::Glue::Model::GetTableRequest request;
@@ -372,7 +373,7 @@ bool GlueCatalog::tryGetTableMetadata(
372373
column_type = "timestamptz";
373374
}
374375

375-
schema.push_back({column.GetName(), getType(column_type, can_be_nullable)});
376+
schema.push_back({column.GetName(), getType(column_type, can_be_nullable, getContext())});
376377
}
377378
result.setSchema(schema);
378379
}
@@ -394,9 +395,10 @@ bool GlueCatalog::tryGetTableMetadata(
394395
void GlueCatalog::getTableMetadata(
395396
const std::string & database_name,
396397
const std::string & table_name,
398+
DB::ContextPtr context_,
397399
TableMetadata & result) const
398400
{
399-
if (!tryGetTableMetadata(database_name, table_name, result))
401+
if (!tryGetTableMetadata(database_name, table_name, context_, result))
400402
{
401403
throw DB::Exception(
402404
DB::ErrorCodes::DATALAKE_DATABASE_ERROR,

src/Databases/DataLake/GlueCatalog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ class GlueCatalog final : public ICatalog, private DB::WithContext
4040
void getTableMetadata(
4141
const std::string & database_name,
4242
const std::string & table_name,
43+
DB::ContextPtr context_,
4344
TableMetadata & result) const override;
4445

4546
bool tryGetTableMetadata(
4647
const std::string & database_name,
4748
const std::string & table_name,
49+
DB::ContextPtr context_,
4850
TableMetadata & result) const override;
4951

5052
std::optional<StorageType> getStorageType() const override

src/Databases/DataLake/HiveCatalog.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,21 @@ bool HiveCatalog::existsTable(const std::string & namespace_name, const std::str
9696
return true;
9797
}
9898

99-
void HiveCatalog::getTableMetadata(const std::string & namespace_name, const std::string & table_name, TableMetadata & result) const
99+
void HiveCatalog::getTableMetadata(
100+
const std::string & namespace_name,
101+
const std::string & table_name,
102+
DB::ContextPtr context_,
103+
TableMetadata & result) const
100104
{
101-
if (!tryGetTableMetadata(namespace_name, table_name, result))
105+
if (!tryGetTableMetadata(namespace_name, table_name, context_, result))
102106
throw DB::Exception(DB::ErrorCodes::DATALAKE_DATABASE_ERROR, "No response from iceberg catalog");
103107
}
104108

105-
bool HiveCatalog::tryGetTableMetadata(const std::string & namespace_name, const std::string & table_name, TableMetadata & result) const
109+
bool HiveCatalog::tryGetTableMetadata(
110+
const std::string & namespace_name,
111+
const std::string & table_name,
112+
DB::ContextPtr context_,
113+
TableMetadata & result) const
106114
{
107115
Apache::Hadoop::Hive::Table table;
108116

@@ -130,7 +138,7 @@ bool HiveCatalog::tryGetTableMetadata(const std::string & namespace_name, const
130138
auto columns = table.sd.cols;
131139
for (const auto & column : columns)
132140
{
133-
schema.push_back({column.name, getType(column.type, true)});
141+
schema.push_back({column.name, getType(column.type, true, context_)});
134142
}
135143
result.setSchema(schema);
136144
}

src/Databases/DataLake/HiveCatalog.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,17 @@ class HiveCatalog final : public ICatalog, private DB::WithContext
3838

3939
bool existsTable(const std::string & namespace_name, const std::string & table_name) const override;
4040

41-
void getTableMetadata(const std::string & namespace_name, const std::string & table_name, TableMetadata & result) const override;
42-
43-
bool tryGetTableMetadata(const std::string & namespace_name, const std::string & table_name, TableMetadata & result) const override;
41+
void getTableMetadata(
42+
const std::string & namespace_name,
43+
const std::string & table_name,
44+
DB::ContextPtr context_,
45+
TableMetadata & result) const override;
46+
47+
bool tryGetTableMetadata(
48+
const std::string & namespace_name,
49+
const std::string & table_name,
50+
DB::ContextPtr context_,
51+
TableMetadata & result) const override;
4452

4553
std::optional<StorageType> getStorageType() const override;
4654

src/Databases/DataLake/ICatalog.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88
#include <Databases/DataLake/DatabaseDataLakeStorageType.h>
99
#include <Poco/JSON/Object.h>
1010

11+
namespace DB
12+
{
13+
14+
class Context;
15+
using ContextPtr = std::shared_ptr<const Context>;
16+
17+
}
18+
1119
namespace DataLake
1220
{
1321

@@ -150,13 +158,15 @@ class ICatalog
150158
virtual void getTableMetadata(
151159
const std::string & namespace_name,
152160
const std::string & table_name,
161+
DB::ContextPtr context,
153162
TableMetadata & result) const = 0;
154163

155164
/// Get table metadata in the given namespace.
156165
/// Return `false` if table does not exist, `true` otherwise.
157166
virtual bool tryGetTableMetadata(
158167
const std::string & namespace_name,
159168
const std::string & table_name,
169+
DB::ContextPtr context,
160170
TableMetadata & result) const = 0;
161171

162172
/// Get storage type, where Iceberg tables' data is stored.

0 commit comments

Comments
 (0)