@@ -439,7 +439,7 @@ struct DuckLakeDataFile {
439
439
}
440
440
441
441
public:
442
- // ! Contains the stats used to write the 'ducklake_file_column_statistics '
442
+ // ! Contains the stats used to write the 'ducklake_file_column_stats '
443
443
IcebergManifestEntry manifest_entry;
444
444
DuckLakePartition &partition;
445
445
@@ -1001,7 +1001,7 @@ struct IcebergToDuckLakeBindData : public TableFunctionData {
1001
1001
public:
1002
1002
vector<string> CreateSQLStatements () {
1003
1003
// ! Order to process in:
1004
- // - snapshot
1004
+ // - snapshot + schema_versions
1005
1005
// - schema
1006
1006
// - table
1007
1007
// - partition_info
@@ -1026,6 +1026,13 @@ struct IcebergToDuckLakeBindData : public TableFunctionData {
1026
1026
auto &snapshot = it.second ;
1027
1027
1028
1028
auto values = snapshot.FinalizeEntry (serializer);
1029
+ if (snapshot.catalog_changes ) {
1030
+ auto snapshot_id = snapshot.snapshot_id ;
1031
+ auto schema_version = snapshot.base_schema_version ;
1032
+ sql.push_back (
1033
+ StringUtil::Format (" INSERT INTO {METADATA_CATALOG}.ducklake_schema_versions VALUES (%llu, %llu);" ,
1034
+ snapshot_id.GetIndex (), schema_version));
1035
+ }
1029
1036
sql.push_back (StringUtil::Format (" INSERT INTO {METADATA_CATALOG}.ducklake_snapshot %s" , values));
1030
1037
}
1031
1038
@@ -1083,7 +1090,7 @@ struct IcebergToDuckLakeBindData : public TableFunctionData {
1083
1090
auto data_file_id = data_file.data_file_id .GetIndex ();
1084
1091
auto &start_snapshot = snapshots.at (data_file.start_snapshot );
1085
1092
1086
- // ! ducklake_file_column_statistics
1093
+ // ! ducklake_file_column_stats
1087
1094
auto columns = table.GetColumnsAtSnapshot (start_snapshot);
1088
1095
for (auto &it : columns) {
1089
1096
auto column_id = it.first ;
@@ -1130,11 +1137,11 @@ struct IcebergToDuckLakeBindData : public TableFunctionData {
1130
1137
auto contains_nan = stats.has_nan ? " true" : " false" ;
1131
1138
auto min_value = stats.lower_bound .IsNull () ? " NULL" : " '" + stats.lower_bound .ToString () + " '" ;
1132
1139
auto max_value = stats.upper_bound .IsNull () ? " NULL" : " '" + stats.upper_bound .ToString () + " '" ;
1133
- auto values = StringUtil::Format (" VALUES(%d, %d, %d, %s, %s, %s, %s, %s, %s);" , data_file_id,
1140
+ auto values = StringUtil::Format (" VALUES(%d, %d, %d, %s, %s, %s, %s, %s, %s, NULL );" , data_file_id,
1134
1141
table_id, column_id, column_size_bytes, value_count,
1135
1142
null_count.ToString (), min_value, max_value, contains_nan);
1136
- sql.push_back (StringUtil::Format (
1137
- " INSERT INTO {METADATA_CATALOG}.ducklake_file_column_statistics %s" , values));
1143
+ sql.push_back (
1144
+ StringUtil::Format ( " INSERT INTO {METADATA_CATALOG}.ducklake_file_column_stats %s" , values));
1138
1145
1139
1146
if (!data_file.has_end && !column.has_end && !column.IsNested ()) {
1140
1147
// ! This data file is currently active, collect stats for it
@@ -1218,8 +1225,8 @@ struct IcebergToDuckLakeBindData : public TableFunctionData {
1218
1225
auto contains_nan = stats.contains_nan ? " true" : " false" ;
1219
1226
auto min_value = stats.min_value .IsNull () ? " NULL" : " '" + stats.min_value .ToString () + " '" ;
1220
1227
auto max_value = stats.max_value .IsNull () ? " NULL" : " '" + stats.max_value .ToString () + " '" ;
1221
- auto values = StringUtil::Format (" VALUES(%d, %d, %s, %s, %s, %s);" , table_id, column_id, contains_null ,
1222
- contains_nan, min_value, max_value);
1228
+ auto values = StringUtil::Format (" VALUES(%d, %d, %s, %s, %s, %s, NULL );" , table_id, column_id,
1229
+ contains_null, contains_nan, min_value, max_value);
1223
1230
sql.push_back (
1224
1231
StringUtil::Format (" INSERT INTO {METADATA_CATALOG}.ducklake_table_column_stats %s" , values));
1225
1232
}
@@ -1286,7 +1293,8 @@ struct IcebergToDuckLakeBindData : public TableFunctionData {
1286
1293
changes.push_back (StringUtil::Format (" altered_table:%d" , table_id));
1287
1294
}
1288
1295
auto snapshot_id = snapshot.snapshot_id .GetIndex ();
1289
- auto values = StringUtil::Format (" VALUES(%d, '%s');" , snapshot_id, StringUtil::Join (changes, " ," ));
1296
+ auto values =
1297
+ StringUtil::Format (" VALUES(%d, '%s', NULL, NULL, NULL);" , snapshot_id, StringUtil::Join (changes, " ," ));
1290
1298
sql.push_back (StringUtil::Format (" INSERT INTO {METADATA_CATALOG}.ducklake_snapshot_changes %s" , values));
1291
1299
}
1292
1300
sql.push_back (" COMMIT TRANSACTION;" );
@@ -1452,8 +1460,9 @@ struct IcebergToDuckLakeGlobalTableFunctionState : public GlobalTableFunctionSta
1452
1460
" DuckLake version metadata is corrupt, the value can't be NULL and has to be of type VARCHAR" );
1453
1461
}
1454
1462
auto version_string = value.GetValue <string>();
1455
- if (version_string != " 0.2" ) {
1456
- throw InvalidInputException (" 'iceberg_to_ducklake' only support version 0.2 currently" );
1463
+ if (!StringUtil::StartsWith (version_string, " 0.3" )) {
1464
+ throw InvalidInputException (
1465
+ " 'iceberg_to_ducklake' only support version 0.3 currently, detected '%s' instead" , version_string);
1457
1466
}
1458
1467
}
1459
1468
0 commit comments