duckdb 0.6.2-dev2085.0 → 0.6.2-dev2094.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb/extension/parquet/parquet_writer.cpp +17 -1
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +52 -33
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_table_entry.hpp +3 -0
- package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +33 -2
package/package.json
CHANGED
|
@@ -211,6 +211,19 @@ void ParquetWriter::SetSchemaProperties(const LogicalType &duckdb_type,
|
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
void VerifyUniqueNames(const vector<string> &names) {
|
|
215
|
+
#ifdef DEBUG
|
|
216
|
+
unordered_set<string> name_set;
|
|
217
|
+
name_set.reserve(names.size());
|
|
218
|
+
for (auto &column : names) {
|
|
219
|
+
auto res = name_set.insert(column);
|
|
220
|
+
D_ASSERT(res.second == true);
|
|
221
|
+
}
|
|
222
|
+
// If there would be duplicates, these sizes would differ
|
|
223
|
+
D_ASSERT(name_set.size() == names.size());
|
|
224
|
+
#endif
|
|
225
|
+
}
|
|
226
|
+
|
|
214
227
|
ParquetWriter::ParquetWriter(FileSystem &fs, string file_name_p, FileOpener *file_opener_p, vector<LogicalType> types_p,
|
|
215
228
|
vector<string> names_p, CompressionCodec::type codec)
|
|
216
229
|
: file_name(std::move(file_name_p)), sql_types(std::move(types_p)), column_names(std::move(names_p)), codec(codec) {
|
|
@@ -237,10 +250,13 @@ ParquetWriter::ParquetWriter(FileSystem &fs, string file_name_p, FileOpener *fil
|
|
|
237
250
|
file_meta_data.schema[0].repetition_type = duckdb_parquet::format::FieldRepetitionType::REQUIRED;
|
|
238
251
|
file_meta_data.schema[0].__isset.repetition_type = true;
|
|
239
252
|
|
|
253
|
+
auto &unique_names = column_names;
|
|
254
|
+
VerifyUniqueNames(unique_names);
|
|
255
|
+
|
|
240
256
|
vector<string> schema_path;
|
|
241
257
|
for (idx_t i = 0; i < sql_types.size(); i++) {
|
|
242
258
|
column_writers.push_back(ColumnWriter::CreateWriterRecursive(file_meta_data.schema, *this, sql_types[i],
|
|
243
|
-
|
|
259
|
+
unique_names[i], schema_path));
|
|
244
260
|
}
|
|
245
261
|
}
|
|
246
262
|
|
|
@@ -300,37 +300,13 @@ unique_ptr<CatalogEntry> DuckTableEntry::AddColumn(ClientContext &context, AddCo
|
|
|
300
300
|
return make_unique<DuckTableEntry>(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), new_storage);
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
throw CatalogException("Cannot drop column: rowid column cannot be dropped");
|
|
308
|
-
}
|
|
309
|
-
return nullptr;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
auto create_info = make_unique<CreateTableInfo>(schema, name);
|
|
313
|
-
create_info->temporary = temporary;
|
|
314
|
-
|
|
315
|
-
logical_index_set_t removed_columns;
|
|
316
|
-
if (column_dependency_manager.HasDependents(removed_index)) {
|
|
317
|
-
removed_columns = column_dependency_manager.GetDependents(removed_index);
|
|
318
|
-
}
|
|
319
|
-
if (!removed_columns.empty() && !info.cascade) {
|
|
320
|
-
throw CatalogException("Cannot drop column: column is a dependency of 1 or more generated column(s)");
|
|
321
|
-
}
|
|
322
|
-
for (auto &col : columns.Logical()) {
|
|
323
|
-
if (col.Logical() == removed_index || removed_columns.count(col.Logical())) {
|
|
324
|
-
continue;
|
|
325
|
-
}
|
|
326
|
-
create_info->columns.AddColumn(col.Copy());
|
|
327
|
-
}
|
|
328
|
-
if (create_info->columns.empty()) {
|
|
329
|
-
throw CatalogException("Cannot drop column: table only has one column remaining!");
|
|
330
|
-
}
|
|
331
|
-
auto adjusted_indices = column_dependency_manager.RemoveColumn(removed_index, columns.LogicalColumnCount());
|
|
303
|
+
void DuckTableEntry::UpdateConstraintsOnColumnDrop(const LogicalIndex &removed_index,
|
|
304
|
+
const vector<LogicalIndex> &adjusted_indices,
|
|
305
|
+
const RemoveColumnInfo &info, CreateTableInfo &create_info,
|
|
306
|
+
bool is_generated) {
|
|
332
307
|
// handle constraints for the new table
|
|
333
308
|
D_ASSERT(constraints.size() == bound_constraints.size());
|
|
309
|
+
|
|
334
310
|
for (idx_t constr_idx = 0; constr_idx < constraints.size(); constr_idx++) {
|
|
335
311
|
auto &constraint = constraints[constr_idx];
|
|
336
312
|
auto &bound_constraint = bound_constraints[constr_idx];
|
|
@@ -342,14 +318,20 @@ unique_ptr<CatalogEntry> DuckTableEntry::RemoveColumn(ClientContext &context, Re
|
|
|
342
318
|
// the constraint is not about this column: we need to copy it
|
|
343
319
|
// we might need to shift the index back by one though, to account for the removed column
|
|
344
320
|
auto new_index = adjusted_indices[not_null_index.index];
|
|
345
|
-
create_info
|
|
321
|
+
create_info.constraints.push_back(make_unique<NotNullConstraint>(new_index));
|
|
346
322
|
}
|
|
347
323
|
break;
|
|
348
324
|
}
|
|
349
325
|
case ConstraintType::CHECK: {
|
|
326
|
+
// Generated columns can not be part of an index
|
|
350
327
|
// CHECK constraint
|
|
351
328
|
auto &bound_check = (BoundCheckConstraint &)*bound_constraint;
|
|
352
329
|
// check if the removed column is part of the check constraint
|
|
330
|
+
if (is_generated) {
|
|
331
|
+
// generated columns can not be referenced by constraints, we can just add the constraint back
|
|
332
|
+
create_info.constraints.push_back(constraint->Copy());
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
353
335
|
auto physical_index = columns.LogicalToPhysical(removed_index);
|
|
354
336
|
if (bound_check.bound_columns.find(physical_index) != bound_check.bound_columns.end()) {
|
|
355
337
|
if (bound_check.bound_columns.size() > 1) {
|
|
@@ -362,7 +344,7 @@ unique_ptr<CatalogEntry> DuckTableEntry::RemoveColumn(ClientContext &context, Re
|
|
|
362
344
|
}
|
|
363
345
|
} else {
|
|
364
346
|
// check constraint does not concern the removed column: simply re-add it
|
|
365
|
-
create_info
|
|
347
|
+
create_info.constraints.push_back(constraint->Copy());
|
|
366
348
|
}
|
|
367
349
|
break;
|
|
368
350
|
}
|
|
@@ -377,7 +359,7 @@ unique_ptr<CatalogEntry> DuckTableEntry::RemoveColumn(ClientContext &context, Re
|
|
|
377
359
|
}
|
|
378
360
|
unique.index = adjusted_indices[unique.index.index];
|
|
379
361
|
}
|
|
380
|
-
create_info
|
|
362
|
+
create_info.constraints.push_back(std::move(copy));
|
|
381
363
|
break;
|
|
382
364
|
}
|
|
383
365
|
case ConstraintType::FOREIGN_KEY: {
|
|
@@ -398,13 +380,50 @@ unique_ptr<CatalogEntry> DuckTableEntry::RemoveColumn(ClientContext &context, Re
|
|
|
398
380
|
info.removed_column);
|
|
399
381
|
}
|
|
400
382
|
}
|
|
401
|
-
create_info
|
|
383
|
+
create_info.constraints.push_back(std::move(copy));
|
|
402
384
|
break;
|
|
403
385
|
}
|
|
404
386
|
default:
|
|
405
387
|
throw InternalException("Unsupported constraint for entry!");
|
|
406
388
|
}
|
|
407
389
|
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
unique_ptr<CatalogEntry> DuckTableEntry::RemoveColumn(ClientContext &context, RemoveColumnInfo &info) {
|
|
393
|
+
auto removed_index = GetColumnIndex(info.removed_column, info.if_column_exists);
|
|
394
|
+
if (!removed_index.IsValid()) {
|
|
395
|
+
if (!info.if_column_exists) {
|
|
396
|
+
throw CatalogException("Cannot drop column: rowid column cannot be dropped");
|
|
397
|
+
}
|
|
398
|
+
return nullptr;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
auto create_info = make_unique<CreateTableInfo>(schema, name);
|
|
402
|
+
create_info->temporary = temporary;
|
|
403
|
+
|
|
404
|
+
logical_index_set_t removed_columns;
|
|
405
|
+
if (column_dependency_manager.HasDependents(removed_index)) {
|
|
406
|
+
removed_columns = column_dependency_manager.GetDependents(removed_index);
|
|
407
|
+
}
|
|
408
|
+
if (!removed_columns.empty() && !info.cascade) {
|
|
409
|
+
throw CatalogException("Cannot drop column: column is a dependency of 1 or more generated column(s)");
|
|
410
|
+
}
|
|
411
|
+
bool dropped_column_is_generated = false;
|
|
412
|
+
for (auto &col : columns.Logical()) {
|
|
413
|
+
if (col.Logical() == removed_index || removed_columns.count(col.Logical())) {
|
|
414
|
+
if (col.Generated()) {
|
|
415
|
+
dropped_column_is_generated = true;
|
|
416
|
+
}
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
create_info->columns.AddColumn(col.Copy());
|
|
420
|
+
}
|
|
421
|
+
if (create_info->columns.empty()) {
|
|
422
|
+
throw CatalogException("Cannot drop column: table only has one column remaining!");
|
|
423
|
+
}
|
|
424
|
+
auto adjusted_indices = column_dependency_manager.RemoveColumn(removed_index, columns.LogicalColumnCount());
|
|
425
|
+
|
|
426
|
+
UpdateConstraintsOnColumnDrop(removed_index, adjusted_indices, info, *create_info, dropped_column_is_generated);
|
|
408
427
|
|
|
409
428
|
auto binder = Binder::CreateBinder(context);
|
|
410
429
|
auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
|
2
|
-
#define DUCKDB_VERSION "0.6.2-
|
|
2
|
+
#define DUCKDB_VERSION "0.6.2-dev2094"
|
|
3
3
|
#endif
|
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
|
5
|
+
#define DUCKDB_SOURCE_ID "4552228a14"
|
|
6
6
|
#endif
|
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
|
8
8
|
#include "duckdb/main/database.hpp"
|
|
@@ -57,6 +57,9 @@ private:
|
|
|
57
57
|
unique_ptr<CatalogEntry> AddForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info);
|
|
58
58
|
unique_ptr<CatalogEntry> DropForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info);
|
|
59
59
|
|
|
60
|
+
void UpdateConstraintsOnColumnDrop(const LogicalIndex &removed_index, const vector<LogicalIndex> &adjusted_indices,
|
|
61
|
+
const RemoveColumnInfo &info, CreateTableInfo &create_info, bool is_generated);
|
|
62
|
+
|
|
60
63
|
private:
|
|
61
64
|
//! A reference to the underlying storage unit used for this table
|
|
62
65
|
std::shared_ptr<DataTable> storage;
|
|
@@ -33,6 +33,34 @@ static vector<idx_t> ColumnListToIndices(const vector<bool> &vec) {
|
|
|
33
33
|
return ret;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
vector<string> GetUniqueNames(const vector<string> &original_names) {
|
|
37
|
+
unordered_set<string> name_set;
|
|
38
|
+
vector<string> unique_names;
|
|
39
|
+
unique_names.reserve(original_names.size());
|
|
40
|
+
|
|
41
|
+
for (auto &name : original_names) {
|
|
42
|
+
auto insert_result = name_set.insert(name);
|
|
43
|
+
if (insert_result.second == false) {
|
|
44
|
+
// Could not be inserted, name already exists
|
|
45
|
+
idx_t index = 1;
|
|
46
|
+
string postfixed_name;
|
|
47
|
+
while (true) {
|
|
48
|
+
postfixed_name = StringUtil::Format("%s:%d", name, index);
|
|
49
|
+
auto res = name_set.insert(postfixed_name);
|
|
50
|
+
if (!res.second) {
|
|
51
|
+
index++;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
unique_names.push_back(postfixed_name);
|
|
57
|
+
} else {
|
|
58
|
+
unique_names.push_back(name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return unique_names;
|
|
62
|
+
}
|
|
63
|
+
|
|
36
64
|
BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
|
|
37
65
|
// COPY TO a file
|
|
38
66
|
auto &config = DBConfig::GetConfig(context);
|
|
@@ -99,8 +127,10 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
|
|
|
99
127
|
use_tmp_file = is_file_and_exists && !per_thread_output && partition_cols.empty() && !is_stdout;
|
|
100
128
|
}
|
|
101
129
|
|
|
130
|
+
auto unique_column_names = GetUniqueNames(select_node.names);
|
|
131
|
+
|
|
102
132
|
auto function_data =
|
|
103
|
-
copy_function->function.copy_to_bind(context, *stmt.info,
|
|
133
|
+
copy_function->function.copy_to_bind(context, *stmt.info, unique_column_names, select_node.types);
|
|
104
134
|
// now create the copy information
|
|
105
135
|
auto copy = make_unique<LogicalCopyToFile>(copy_function->function, std::move(function_data));
|
|
106
136
|
copy->file_path = stmt.info->file_path;
|
|
@@ -110,7 +140,8 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
|
|
|
110
140
|
copy->per_thread_output = per_thread_output;
|
|
111
141
|
copy->partition_output = !partition_cols.empty();
|
|
112
142
|
copy->partition_columns = std::move(partition_cols);
|
|
113
|
-
|
|
143
|
+
|
|
144
|
+
copy->names = unique_column_names;
|
|
114
145
|
copy->expected_types = select_node.types;
|
|
115
146
|
|
|
116
147
|
copy->AddChild(std::move(select_node.plan));
|