-
Notifications
You must be signed in to change notification settings - Fork 92
feat(datafusion): add SHOW, ADD and DROP PARTITION for catalog-managed format tables - #816
Open
sundapeng wants to merge 3 commits into
Open
feat(datafusion): add SHOW, ADD and DROP PARTITION for catalog-managed format tables #816sundapeng wants to merge 3 commits into
sundapeng wants to merge 3 commits into
Conversation
...d format tables A Format Table whose partitions a REST catalog manages is read from its registrations, but DataFusion could not change them. This adds the statements that do: - SHOW PARTITIONS [PARTITION (...)] lists the registrations in escaped key=value form, read with the column types and optionally filtered by any subset of partition values. - ALTER TABLE ... ADD [IF NOT EXISTS] PARTITION (...) registers complete specs, then creates their directories. - ALTER TABLE ... DROP [IF EXISTS] PARTITION (...) takes several specifications, expands a partial one to every registered partition it matches and compares values as the catalog holds them, so `month = 1` does not select `month=01`, as Java resolveFormatTablePartitionsForDrop does. Complete specifications are looked up by name; a partial one reads the registry once. Registrations go first and directories after; a partition at a custom location is only unregistered. Partition literals are read with the column type through the parser that reads registrations and directories, the way Java casts partition strings, so a BOOLEAN value accepts t/true/y/yes/1 and their false counterparts. Catalog gains drop_partitions. RESTCatalog refuses it for a table without catalog-managed partitions, since the endpoint only removes metadata and would leave the data of any other table in place while reporting success.
...bles Describe catalog-managed Format Table partitions in the SQL guide: the metastore.partitioned-table prerequisite, SHOW / ADD / DROP PARTITION, how partition values are read, what each statement does to registrations and directories, and how a partition at a custom location is treated.
Comment on lines
+3520
to
+3527
parse_format_partition_value(&text, data_type)
.and_then(|datum| {
format_partition_value(
&datum,
data_type,
options.partition_default_name(),
options.legacy_partition_name(),
)
Member
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.
format_partition_value maps empty and whitespace-only strings to the default partition name. As a result, DROP PARTITION (dt = '') deletes the NULL partition, including its files—I reproduced this locally. Please reject these literals before formatting and add a regression test.
Member
Author
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.
Agreed, fixed in c0fe18c.
... PARTITION A blank string for a string partition column is formatted as the default partition name, so DROP PARTITION (dt = '') unregistered the NULL partition and deleted its directory, and ADD PARTITION (dt = '') registered it. Refuse an empty or whitespace-only string for a string partition column in ADD and DROP PARTITION, as Java PaimonFormatTable.requireNameablePartitionValues does. SHOW PARTITIONS still accepts it as a filter.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Uh oh!
There was an error while loading. Please reload this page.
Purpose
Child of #591, which stays open as a draft that shows the full feature; its remaining changes reach
mainthrough child PRs.A Format Table loaded from a REST catalog with
metastore.partitioned-table=truehas its partitions registered in the catalog, and since #814 a scan reads exactly those registrations. DataFusion could not list or change them. This PR addsSHOW PARTITIONSandALTER TABLE ... ADD / DROP PARTITIONfor such tables.Depends on: nothing. It is based on
main, where #811, #813, #812 and #814 have merged.MSCK REPAIR TABLE(<MSCK_PR>) andANALYZE TABLE(#815) build on this PR.Brief change log
SHOW PARTITIONS table [PARTITION (...)]lists the registered partitions in escapedkey=value/...form, sorted. Values are read with the column type: a DATE registered as epoch days prints asdt=2026年07月22日,month=01andmonth=1both print asmonth=1, and the default partition prints asnull. The optionalPARTITION (...)clause filters by any subset of partition values, compared the same way.ALTER TABLE table ADD [IF NOT EXISTS] PARTITION (...) [PARTITION (...)]registers complete specifications with the catalog, then creates their directories.LOCATIONis refused.ALTER TABLE table DROP [IF EXISTS] PARTITION (...)follows JavaresolveFormatTablePartitionsForDrop:IF EXISTSis given;month = 1does not select a partition registered asmonth=01;list-by-names; one with a partial specification reads the registry once;options.path) is only unregistered and its data is left in place;ALTER TABLEoperations.DATE '...'as written, booleans astrue/false, numbers in canonical form,NULLas the default partition), andparse_format_partition_valuereads it with the column type, asTypeUtils.castFromStringdoes. Somonth = '01'andmonth = 01both namemonth=1, a BOOLEAN acceptst/true/y/yes/1andf/false/n/no/0, and a DATE acceptsyyyy-MM-dd. An invalid value fails with its column named.PaimonFormatTable.requireNameablePartitionValuesdoes.Catalog::drop_partitions, with a default that returnsUnsupported.RESTCatalogsends it in batches of 1000 and refuses tables without catalog-managed partitions.FormatTablePartitionPaths,format_partition_valueandparse_format_partition_valuebecome public inpaimon::table.Tests
crates/integrations/datafusion/tests/rest_format_partition_sql.rs:test_partition_commands_update_rest_metadata_and_directories: ADD of several partitions, SHOW with and without a filter, DROP, and their directories;test_partition_literals: DATE, INT, BOOLEAN and VARCHAR literals, including Java boolean spellings, unquoted, zero-padded and negative numbers and NULL, with the names and directories they produce, and invalid literals rejected with the column named;test_drop_partition_specifications: partial and non-leading specifications, several specifications, a missing complete specification with and withoutIF EXISTS, an empty partial match, a failing specification leaving the statement unapplied, and the refusal to combine with other operations, each checking the remaining registrations and directories;test_drop_partition_matches_values_as_the_catalog_holds_them: SHOW readsmonth=01andmonth=1with the column type, while DROP compares the values as registered;test_drop_partition_looks_up_complete_specifications_by_name;test_partition_ddl_refuses_blank_string_values: ADD and DROP with an empty or whitespace-only string are refused, and the NULL partition and its directory stay;test_drop_partition_leaves_a_custom_location_in_place;SQLContext::sqlstaysSend.crates/paimon/tests/rest_catalog_test.rs:test_rest_catalog_skips_empty_and_batches_drop_partitions,test_rest_catalog_refuses_to_drop_partitions_it_does_not_manageandtest_rest_catalog_drop_partitions_maps_missing_table.sql_contextunit testtest_drop_if_exists_partition_does_not_ignore_missing_table.Commands run on the top commit:
fmt and clippy pass.
paimon: 2960 tests pass.paimon-rest-server: 10 tests pass.paimon-datafusion: 772 pass, including the 7 tests inrest_format_partition_sql.rs, and 39 fail. The failures are the 39 tests that also fail by name onmainin this environment, because they read fixture tables provisioned bymake docker-up(two also need the lumina native library).Additions without a direct Java counterpart
SQLContextturns SQL partition literals into partition strings itself (partition_literal_to_string): in Java, Spark resolves the partition spec before Paimon sees it, and DataFusion has no such step for these statements. The strings are then read byparse_format_partition_value, the counterpart ofTypeUtils.castFromString.SQLContextparsesSHOW PARTITIONSitself, since sqlparser 0.62 has no such statement.RESTCatalog::drop_partitionsrefuses tables without catalog-managed partitions, where Java commitstruncatePartitions: turning string specs into typed values for every Paimon partition type is not available yet, and the endpoint alone would report success without touching data.sql_future_is_sendtest keeps the future ofSQLContext::sqlSend, which Rust callers need fortokio::spawnand#[async_trait].API and Format
Catalog::drop_partitions, with a default implementation that returnsUnsupported.paimon::table::FormatTablePartitionPaths,format_partition_valueandparse_format_partition_valuebecome public.The storage format is unchanged.
Documentation
docs/src/sql.mdgains a Format Table Partitions section: themetastore.partitioned-tableprerequisite,SHOW/ADD/DROP PARTITION, how partition values are read, the ordering guarantees of ADD and DROP, and how a partition at a custom location is treated. The SQL support scope lists the new statements.Scope and limitations
metastore.partitioned-table=trueand a non-engineimplementation.DROP PARTITIONspecifications are written as repeated clauses,DROP PARTITION (...), DROP PARTITION (...); sqlparser 0.62 cannot parse the Hive formDROP PARTITION (...), (...).