forked from duckdb/ducklake
-
Notifications
You must be signed in to change notification settings - Fork 0
Rebase truncate changes on top of PR #969 #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jprafael
wants to merge
9
commits into
pr-969-base-for-825
Choose a base branch
from
pr-825-rebased-on-969
base: pr-969-base-for-825
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
7358fb8
Add DuckLake truncate operator
jprafael cc066a7
Assert DuckLake truncate plan in tests
jprafael aff193a
Assert delete count invariant in truncate
jprafael 3ce9204
Add more unit tests and cleanup implementation
jprafael c591189
Cleanups
jprafael 97e2240
Fix truncate local inlined data after rebase
jprafael afb91b0
Fix truncate row count on repeated deletes
jprafael f7f6a81
Fix delete history and diagnostics after rebase
jprafael 4d1b155
Avoid iterating rows for inlined truncate
jprafael File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // DuckDB | ||
| // | ||
| // storage/ducklake_truncate.hpp | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "duckdb/execution/physical_operator.hpp" | ||
| #include "storage/ducklake_table_entry.hpp" | ||
|
|
||
| namespace duckdb { | ||
|
|
||
| class DuckLakeTruncate : public PhysicalOperator { | ||
| public: | ||
| DuckLakeTruncate(PhysicalPlan &physical_plan, DuckLakeTableEntry &table); | ||
|
|
||
| DuckLakeTableEntry &table; | ||
|
|
||
| public: | ||
| SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, | ||
| OperatorSourceInput &input) const override; | ||
|
|
||
| bool IsSource() const override { | ||
| return true; | ||
| } | ||
|
|
||
| unique_ptr<GlobalSourceState> GetGlobalSourceState(ClientContext &context) const override; | ||
|
|
||
| string GetName() const override; | ||
| InsertionOrderPreservingMap<string> ParamsToString() const override; | ||
| }; | ||
|
|
||
| } // namespace duckdb |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // DuckDB | ||
| // | ||
| // storage/ducklake_truncate.cpp | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "storage/ducklake_truncate.hpp" | ||
| #include "storage/ducklake_catalog.hpp" | ||
| #include "storage/ducklake_multi_file_list.hpp" | ||
| #include "storage/ducklake_scan.hpp" | ||
| #include "storage/ducklake_transaction.hpp" | ||
| #include "duckdb/planner/operator/logical_delete.hpp" | ||
| #include "duckdb/planner/operator/logical_get.hpp" | ||
|
|
||
| namespace duckdb { | ||
|
|
||
| class DuckLakeTruncateGlobalState : public GlobalSourceState { | ||
| public: | ||
| bool finished = false; | ||
| }; | ||
|
|
||
| static set<idx_t> GetVisibleInlinedRowIds(DuckLakeTransaction &transaction, DuckLakeSnapshot snapshot, | ||
| const string &inlined_table_name) { | ||
| auto &metadata_manager = transaction.GetMetadataManager(); | ||
| auto query_result = metadata_manager.ReadInlinedData(snapshot, inlined_table_name, {"row_id"}); | ||
| if (query_result->HasError()) { | ||
| query_result->GetErrorObject().Throw("Failed to read inlined row ids during DuckLake truncate: "); | ||
| } | ||
|
|
||
| set<idx_t> row_ids; | ||
| for (auto &row : *query_result) { | ||
| row_ids.insert(row.GetValue<idx_t>(0)); | ||
| } | ||
| return row_ids; | ||
| } | ||
|
|
||
| DuckLakeTruncate::DuckLakeTruncate(PhysicalPlan &physical_plan, DuckLakeTableEntry &table) | ||
| : PhysicalOperator(physical_plan, PhysicalOperatorType::EXTENSION, {LogicalType::UBIGINT}, 0), table(table) { | ||
| } | ||
|
|
||
| unique_ptr<GlobalSourceState> DuckLakeTruncate::GetGlobalSourceState(ClientContext &context) const { | ||
| return make_uniq<DuckLakeTruncateGlobalState>(); | ||
| } | ||
|
|
||
| SourceResultType DuckLakeTruncate::GetDataInternal(ExecutionContext &context, DataChunk &chunk, | ||
| OperatorSourceInput &input) const { | ||
| auto &gstate = input.global_state.Cast<DuckLakeTruncateGlobalState>(); | ||
| if (gstate.finished) { | ||
| return SourceResultType::FINISHED; | ||
| } | ||
| gstate.finished = true; | ||
|
|
||
| auto &transaction = DuckLakeTransaction::Get(context.client, table.catalog); | ||
| DuckLakeFunctionInfo read_info(table, transaction, transaction.GetSnapshot()); | ||
| auto transaction_local_files = transaction.GetTransactionLocalFiles(table.GetTableId()); | ||
| auto transaction_local_data = transaction.GetTransactionLocalInlinedData(table.GetTableId()); | ||
| DuckLakeMultiFileList file_list(read_info, std::move(transaction_local_files), transaction_local_data); | ||
|
|
||
| uint64_t total_deleted_count = table.GetNetDataFileRowCount(transaction) + table.GetNetInlinedRowCount(transaction); | ||
| auto files = file_list.GetFilesExtended(); | ||
| for (auto &file_info : files) { | ||
| switch (file_info.data_type) { | ||
| case DuckLakeDataType::DATA_FILE: { | ||
| if (file_info.file_id.IsValid()) { | ||
| transaction.DropFile(table.GetTableId(), file_info.file_id, file_info.file.path); | ||
| } else { | ||
| transaction.DropTransactionLocalFile(table.GetTableId(), file_info.file.path); | ||
| } | ||
| break; | ||
| } | ||
| case DuckLakeDataType::INLINED_DATA: { | ||
| auto row_ids = GetVisibleInlinedRowIds(transaction, read_info.snapshot, file_info.file.path); | ||
| transaction.AddNewInlinedDeletes(table.GetTableId(), file_info.file.path, std::move(row_ids)); | ||
| break; | ||
| } | ||
| case DuckLakeDataType::TRANSACTION_LOCAL_INLINED_DATA: { | ||
| transaction.TruncateLocalInlinedData(table.GetTableId()); | ||
| break; | ||
| } | ||
| default: | ||
| throw InternalException("Unsupported DuckLakeDataType in truncate"); | ||
| } | ||
| } | ||
|
|
||
| chunk.SetCardinality(1); | ||
| chunk.SetValue(0, 0, Value::UBIGINT(total_deleted_count)); | ||
| return SourceResultType::FINISHED; | ||
| } | ||
|
|
||
| string DuckLakeTruncate::GetName() const { | ||
| return "DUCKLAKE_TRUNCATE"; | ||
| } | ||
|
|
||
| InsertionOrderPreservingMap<string> DuckLakeTruncate::ParamsToString() const { | ||
| InsertionOrderPreservingMap<string> result; | ||
| result["Table Name"] = table.name; | ||
| return result; | ||
| } | ||
|
|
||
| PhysicalOperator &DuckLakeCatalog::PlanDelete(ClientContext &context, PhysicalPlanGenerator &planner, LogicalDelete &op) { | ||
| bool delete_all = false; | ||
| if (op.children.size() == 1 && op.children[0]->type == LogicalOperatorType::LOGICAL_GET) { | ||
| auto &get = op.children[0]->Cast<LogicalGet>(); | ||
| delete_all = get.table_filters.filters.empty(); | ||
| } | ||
| if (!delete_all) { | ||
| return Catalog::PlanDelete(context, planner, op); | ||
| } | ||
| auto &table = op.table.Cast<DuckLakeTableEntry>(); | ||
| auto &transaction = DuckLakeTransaction::Get(context, *this); | ||
| if (transaction.HasAnyLocalChanges(table.GetTableId())) { | ||
| return Catalog::PlanDelete(context, planner, op); | ||
| } | ||
| if (op.return_chunk) { | ||
| throw BinderException("RETURNING clause not yet supported for deletion of a DuckLake table"); | ||
| } | ||
| return planner.Make<DuckLakeTruncate>(table); | ||
| } | ||
|
|
||
| } // namespace duckdb | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # name: test/sql/delete/ducklake_delete_all_simple.test | ||
| # description: simple delete-all on ducklake table | ||
|
|
||
| require ducklake | ||
|
|
||
| require parquet | ||
|
|
||
| test-env DUCKLAKE_CONNECTION __TEST_DIR__/{UUID}.db | ||
|
|
||
| test-env DATA_PATH __TEST_DIR__ | ||
|
|
||
| statement ok | ||
| ATTACH 'ducklake:${DUCKLAKE_CONNECTION}' AS ducklake (DATA_PATH '${DATA_PATH}/ducklake_delete_all_simple') | ||
|
|
||
| statement ok | ||
| CREATE TABLE ducklake.delete_all_test(i INTEGER); | ||
|
|
||
| statement ok | ||
| INSERT INTO ducklake.delete_all_test FROM range(10); | ||
|
|
||
| query II | ||
| EXPLAIN DELETE FROM ducklake.delete_all_test; | ||
| ---- | ||
| physical_plan <REGEX>:.*DUCKLAKE_TRUNCATE.* | ||
|
|
||
| query I | ||
| SELECT COUNT(*) FROM ducklake.delete_all_test; | ||
| ---- | ||
| 10 | ||
|
|
||
| statement ok | ||
| DELETE FROM ducklake.delete_all_test; | ||
|
|
||
| query I | ||
| SELECT COUNT(*) FROM ducklake.delete_all_test; | ||
| ---- | ||
| 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # name: test/sql/delete/ducklake_truncate_simple.test | ||
| # description: simple TRUNCATE on ducklake table | ||
|
|
||
| require ducklake | ||
|
|
||
| require parquet | ||
|
|
||
| test-env DUCKLAKE_CONNECTION __TEST_DIR__/{UUID}.db | ||
|
|
||
| test-env DATA_PATH __TEST_DIR__ | ||
|
|
||
| statement ok | ||
| ATTACH 'ducklake:${DUCKLAKE_CONNECTION}' AS ducklake (DATA_PATH '${DATA_PATH}/ducklake_truncate_simple') | ||
|
|
||
| statement ok | ||
| CREATE TABLE ducklake.truncate_test(i INTEGER); | ||
|
|
||
| statement ok | ||
| INSERT INTO ducklake.truncate_test FROM range(10); | ||
|
|
||
| query II | ||
| EXPLAIN TRUNCATE ducklake.truncate_test; | ||
| ---- | ||
| physical_plan <REGEX>:.*DUCKLAKE_TRUNCATE.* | ||
|
|
||
| query I | ||
| SELECT COUNT(*) FROM ducklake.truncate_test; | ||
| ---- | ||
| 10 | ||
|
|
||
| statement ok | ||
| TRUNCATE ducklake.truncate_test; | ||
|
|
||
| query I | ||
| SELECT COUNT(*) FROM ducklake.truncate_test; | ||
| ---- | ||
| 0 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole purpose of this PR is so that TRUNCATE doesn't have to iterate through rows.
Why can't this just set the entire inline "file" as deleted?