You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bb24345
Browse filesBrowse the repository at this point in the historyBrowse files
refactor: deprecate the bundled statistics providers (#25969)
## Which issue does this PR close?
- Closes#25571.
## Rationale for this change
`StatisticsRegistry::default_with_builtin_providers()` registers
providers that are not the default estimation and that duplicate or
replace what the operators already do in `statistics_from_inputs`. They
can make estimates worse (TPC-H Q14: 14.73 billion rows instead of
73,650, see #25570), and fixes in the operators do not reach their
users. Estimation improvements belong in the operators;
`StatisticsRegistry` stays as the extension point for user-defined
providers.
## What changes are included in this PR?
- `default_with_builtin_providers()` and all seven bundled providers are
deprecated. Their code is unchanged.
- `statistics_registry.slt` and the `join_reorder` example use
user-defined providers instead of bundled ones.
- `dfbench statistics` reports the operators' own estimates instead of
the bundled providers' estimates.
Follow-ups: moving the Filter distinct count survival model into
`FilterExec` (#26052); multi-key join estimation is tracked in #21583.
## What is the testing strategy for this PR?
`statistics_registry.slt` passes unchanged; the `join_reorder` example
still flips the build side.
## Are there any user-facing changes?
Deprecations only, see the 56.0.0 upgrade guide.
----
Disclaimer: I used AI to assist in the code generation, I have manually
reviewed the output and it matches my intention and understanding.
---------
Co-authored-by: Gabriel <45515538+gabotechs@users.noreply.github.com>
| join_reorder |[`statistics/join_reorder.rs`](examples/statistics/join_reorder.rs)| Supply and refine column statistics via a provider to flip a join order |
| join_reorder |[`statistics/join_reorder.rs`](examples/statistics/join_reorder.rs)| Supply catalog column statistics via a provider to flip a join order |
//! The providers bundled in this module are deprecated: the default statistics
43
+
//! estimation is each operator's [`ExecutionPlan::statistics_from_inputs`], and
44
+
//! estimation improvements belong there. Register user-defined providers to
45
+
//! plug in other estimation.
51
46
//!
52
47
//! # Statistics walk
53
48
//!
@@ -392,7 +387,7 @@ impl StatisticsRegistry {
392
387
Self{ providers }
393
388
}
394
389
395
-
/// Create a registry pre-loaded with the standard built-in providers.
390
+
/// Create a registry with the deprecated bundled providers.
396
391
///
397
392
/// Provider order (first match wins):
398
393
/// 1. [`FilterStatisticsProvider`]
@@ -402,6 +397,11 @@ impl StatisticsRegistry {
402
397
/// 5. [`JoinStatisticsProvider`]
403
398
/// 6. [`LimitStatisticsProvider`]
404
399
/// 7. [`UnionStatisticsProvider`]
400
+
#[deprecated(
401
+
since = "56.0.0",
402
+
note = "the bundled providers are deprecated; the statistics walk uses each operator's `statistics_from_inputs` when no provider matches"
403
+
)]
404
+
#[expect(deprecated)]
405
405
pubfndefault_with_builtin_providers() -> Self{
406
406
Self::with_providers(vec![
407
407
Arc::new(FilterStatisticsProvider),
@@ -590,9 +590,14 @@ fn computed_with_row_count(
590
590
/// estimation logic as `FilterExec::statistics_helper`, then additionally
591
591
/// adjusts each column's `distinct_count` using [`ndv_after_selectivity`] based
592
592
/// on the computed selectivity ratio.
593
+
#[deprecated(
594
+
since = "56.0.0",
595
+
note = "duplicates `FilterExec::statistics_from_inputs` and adds a distinct count adjustment that belongs in the operator, see https://github.com/apache/datafusion/issues/26052; without a matching provider the statistics walk uses the operator's own estimate"
@@ -691,9 +701,14 @@ impl StatisticsProvider for ProjectionStatisticsProvider {
691
701
/// transform statistics, so we pass through the enhanced child stats directly.
692
702
/// This avoids the fallback calling `statistics_from_inputs` (overall) which would
693
703
/// trigger a redundant internal recursion with raw (non-enhanced) stats.
704
+
#[deprecated(
705
+
since = "56.0.0",
706
+
note = "duplicates the `statistics_from_inputs` of the cardinality-preserving operators; without a matching provider the statistics walk uses the operator's own estimate"
@@ -835,9 +855,14 @@ impl StatisticsProvider for AggregateStatisticsProvider {
835
855
/// Delegates when:
836
856
/// - The plan is not a supported join type
837
857
/// - Either input lacks row count information
858
+
#[deprecated(
859
+
since = "56.0.0",
860
+
note = "replaces the estimates of `HashJoinExec`, `SortMergeJoinExec` and `CrossJoinExec` with separate estimation logic; without a matching provider the statistics walk uses the operator's own estimate"
861
+
)]
838
862
#[derive(Debug,Default)]
839
863
pubstructJoinStatisticsProvider;
840
864
865
+
#[expect(deprecated)]
841
866
implStatisticsProviderforJoinStatisticsProvider{
842
867
fnmatches(&self,plan:&dynExecutionPlan) -> bool{
843
868
plan.downcast_ref::<HashJoinExec>().is_some()
@@ -960,9 +985,14 @@ impl StatisticsProvider for JoinStatisticsProvider {
960
985
///
961
986
/// Caps output row count at the limit value, accounting for any leading skip offset
962
987
/// in `GlobalLimitExec`.
988
+
#[deprecated(
989
+
since = "56.0.0",
990
+
note = "duplicates the `statistics_from_inputs` of the limit operators; without a matching provider the statistics walk uses the operator's own estimate"
991
+
)]
963
992
#[derive(Debug,Default)]
964
993
pubstructLimitStatisticsProvider;
965
994
995
+
#[expect(deprecated)]
966
996
implStatisticsProviderforLimitStatisticsProvider{
967
997
fnmatches(&self,plan:&dynExecutionPlan) -> bool{
968
998
plan.downcast_ref::<LocalLimitExec>().is_some()
@@ -1011,9 +1041,14 @@ impl StatisticsProvider for LimitStatisticsProvider {
1011
1041
/// Statistics provider for [`UnionExec`].
1012
1042
///
1013
1043
/// Sums row counts across all inputs.
1044
+
#[deprecated(
1045
+
since = "56.0.0",
1046
+
note = "duplicates the `statistics_from_inputs` of `UnionExec`; without a matching provider the statistics walk uses the operator's own estimate"
1047
+
)]
1014
1048
#[derive(Debug,Default)]
1015
1049
pubstructUnionStatisticsProvider;
1016
1050
1051
+
#[expect(deprecated)]
1017
1052
implStatisticsProviderforUnionStatisticsProvider{
1018
1053
fnmatches(&self,plan:&dynExecutionPlan) -> bool{
1019
1054
plan.downcast_ref::<UnionExec>().is_some()
@@ -1134,6 +1169,7 @@ impl StatisticsProvider for ClosureStatisticsProvider {
0 commit comments