-
Notifications
You must be signed in to change notification settings - Fork 92
feat(datafusion): add MSCK REPAIR TABLE for catalog-managed format tables - #817
Draft
sundapeng wants to merge 5 commits into
Draft
feat(datafusion): add MSCK REPAIR TABLE for catalog-managed format tables #817sundapeng wants to merge 5 commits into
sundapeng wants to merge 5 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.
This was referenced Sep 11, 2026
... 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.
...bles
A catalog-managed Format Table reads only the partitions its catalog
registers, so a partition directory written without a registration stays
invisible, and a registration whose directory is gone points at nothing.
MSCK REPAIR TABLE [{ADD|DROP|SYNC} PARTITIONS] reconciles the two:
- ADD, the default, registers every discovered partition the catalog does
not hold; DROP unregisters every registration without a directory; SYNC
does both. Nothing on storage is created or deleted.
- Directory discovery and the catalog listing both finish before any
change, and DROP and SYNC fail on a table directory that cannot be
listed rather than reading it as empty.
- Partitions are matched by escaped name and registered with the values
as their directories spell them, so month=01 stays month=01.
- A partition registered at a custom location is never unregistered,
since its data does not live under the table directory.
FormatTablePartitionPaths gains discover, which skips hidden directories
and segments outside the configured layout, and fails on a matching
segment that is not canonically escaped. unescape_path_name moves from
the scan to spec::partition_utils, beside escape_path_name, so discovery
and the scan share it.
Describe the ADD, DROP and SYNC modes, that repair only changes registrations, that discovery and the catalog listing finish before any change, and that a partition at a custom location is never unregistered.
sundapeng
force-pushed
the
feat/format-table-msck-repair
branch
from
September 12, 2026 06:35
8c6c10a to
fb34c53
Compare
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 with catalog-managed partitions reads only the partitions its catalog registers. A partition directory written by a tool that does not register partitions stays invisible to a scan, and a registration whose directory was removed points at nothing. This PR adds
MSCK REPAIR TABLEfor such tables, following JavaFormatTablePartitionRepair, which backs the same statement in Spark.Depends on #816. Until it merges, this branch includes its three commits; please review only the last two:
feat(datafusion): add MSCK REPAIR TABLE for catalog-managed format tablesanddocs(datafusion): document MSCK REPAIR TABLE for format tables.ANALYZE TABLE(#815) builds on this PR.Brief change log
MSCK REPAIR TABLE table [{ADD|DROP|SYNC} PARTITIONS]on a Format Table with catalog-managed partitions:ADD, which plainMSCK REPAIR TABLEalso means, registers every partition directory the catalog does not hold;DROPunregisters every registration whose directory is gone;SYNCdoes both. New registrations are created, ignoring any that already exist, before any is dropped.key=value/...name and registered with the values their directories spell, so a directorymonth=01is registered asmonth=01, as in Java.options.path) is never unregistered, since its data does not live under the table directory.MSCKwithoutREPAIRand tables without catalog-managed partitions are refused.FormatTablePartitionPaths::discoverfinds the complete partition specs under the table directory, the counterpart of JavaPartitionPathUtils.searchPartSpecAndPathsas repair calls it. Hidden directories are skipped except the value-only default partition directory, segments outside the configured layout and paths shallower than the partition depth are ignored, a missing root holds no partitions, and results are sorted and deduplicated by partition name.unescape_path_namemoves from the Format Table scan tospec::partition_utils, besideescape_path_name, so the scan and discovery share it.Tests
crates/integrations/datafusion/tests/rest_format_partition_sql.rs:test_msck_repair_reconciles_registrations_with_directories: ADD registers a directory the catalog does not know, and SYNC unregisters a partition whose directory was removed while the other directory stays;test_msck_repair_keeps_a_partition_at_a_custom_location: SYNC keeps a partition registered at a custom location even though no directory for it exists under the table.crates/paimon/tests/format_partition_test.rs:discover_format_partitions_returns_complete_sorted_specs,discover_format_partitions_treats_missing_root_as_empty,discover_value_only_partitions_rejects_parent_traversal_valueanddiscover_value_only_partitions_keeps_hidden_default_directory.spec::partition_utils::tests::test_unescape_path_nameandtable::format_partition::tests::test_storage_not_found_matches_only_not_found.Commands run on the top commit:
fmt and clippy pass.
paimon: 2966 tests pass.paimon-rest-server: 10 tests pass.paimon-datafusion: 774 pass, including the 9 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
DROPandSYNClist the table directory before anything else and fail if it cannot be listed. Discovery, like Java's, reads a missing root as a table without partitions; Java's repair has no such check, so a missing table directory would makeDROPorSYNCunregister every partition.unescapePathNamekeeps a malformed escape as written.API and Format
paimon::table::FormatTablePartitionPaths::discover.The storage format is unchanged.
Documentation
docs/src/sql.mdgains anMSCK REPAIR TABLEsubsection under Format Table Partitions and listsMSCK REPAIR TABLEin the SQL support scope.Scope and limitations
metastore.partitioned-table=trueand a non-engineimplementation.format-table.repair.collect-statistics, which also measures the partitions a repair finds, is not supported;ANALYZE TABLE(feat(datafusion): support ANALYZE TABLE on catalog-managed format tables #815 ) measures them afterwards.