Skip to main content

PartialSortExec

Struct PartialSortExec 

Source
pub struct PartialSortExec { /* private fields */ }
Expand description

Sort execution plan for inputs that are already partially sorted.

This operator takes input ordered by a prefix of the required ordering, and produces output ordered by the required ordering, emitting rows sooner (streaming) and using less peak memory than SortExec which must buffer all rows before producing any output.

PartialSortExec relies on the property that rows with the same sort prefix are contiguous, so it can sort one prefix group at a time, emitting completed groups without reading (and buffering) the entire input.

For example, if the required output is (a, b, c), but the input is only ordered by (a, b), PartialSortExec sorts only within each (a, b) group to produce output ordered by (a, b, c).

input ordered by a, b              output ordered by a, b, c

+---+---+---+                      +---+---+---+
| a | b | c |                      | a | b | c |
+---+---+---+                      +---+---+---+
| 0 | 0 | 3 |  --  new group  -->  | 0 | 0 | 1 |
| 0 | 0 | 2 |                      | 0 | 0 | 2 |
| 0 | 0 | 1 |                      | 0 | 0 | 3 |
| 0 | 1 | 1 |  --  new group  -->  | 0 | 1 | 1 |
| 0 | 2 | 4 |  --  new group  -->  | 0 | 2 | 0 |
| 0 | 2 | 0 |                      | 0 | 2 | 4 |
| 1 | 0 | 5 |  --  new group  -->  | 1 | 0 | 5 |
+---+---+---+                      +---+---+---+

§Buffering and Emitting Rows

PartialSortExec buffers rows only until it can prove a prefix group will never be seen again, then sorts and emits buffered rows. A group is guaranteed to never be seen again once a row with a different prefix value arrives. This relies on the input’s existing ordering guarantees.

Using the example from above, rows accumulate in the in-memory buffer in batches. As long as the (a, b) prefix keeps repeating, more rows are buffered.

           Buffer
       +---+---+---+
       | a | b | c |
       +---+---+---+
       | 0 | 0 | 3 |
       | 0 | 0 | 2 |
       | 0 | 0 | 1 |
       +---+---+---+

Once a batch arrives that contains a new (a, b) prefix, e.g. (0, 2): every buffered row for previous prefixes may be emitted:

           Buffer
       +---+---+---+
       | a | b | c |
       +---+---+---+
       | 0 | 0 | 3 |
       | 0 | 0 | 2 |
       | 0 | 0 | 1 |
       | 0 | 1 | 1 |  <-- first row of new batch, new prefix
       | 0 | 2 | 4 |  <-- new prefix
       | 0 | 2 | 0 |
       | 1 | 0 | 5 |  <-- last row of new batch, new prefix
       +---+---+---+

Once known complete, the buffered rows are sorted by the full (a, b, c) ordering and emitted as a RecordBatch; Any rows from the most recently seen prefix remain buffered (as more rows with the same prefix may arrive in future batches.

         Emitted      <-- fully sorted on (a, b, c)
       +---+---+---+
       | a | b | c |
       +---+---+---+
       | 0 | 0 | 1 |   <-- completed group
       | 0 | 0 | 2 |
       | 0 | 0 | 3 |
       | 0 | 2 | 0 |   <-- completed group
       | 0 | 2 | 4 |
       | 0 | 1 | 1 |   <-- completed group
       +---+---+---+

           Buffer
       +---+---+---+
       | a | b | c |
       +---+---+---+
       | 1 | 0 | 5 |   <-- (possibly) in progress group
       +---+---+---+

Implementations§

Source§

impl PartialSortExec

Source

pub fn new( expr: LexOrdering, input: Arc<dyn ExecutionPlan>, common_prefix_length: usize, ) -> Self

Create a new partial sort execution plan

Source

pub fn preserve_partitioning(&self) -> bool

Whether this PartialSortExec preserves partitioning of the children

Source

pub fn with_preserve_partitioning(self, preserve_partitioning: bool) -> Self

Specify the partitioning behavior of this partial sort exec

If preserve_partitioning is true, sorts each partition individually, producing one sorted stream for each input partition.

If preserve_partitioning is false, sorts and merges all input partitions producing a single, sorted partition.

Source

pub fn with_fetch(self, fetch: Option<usize>) -> Self

Modify how many rows to include in the result

If None, then all rows will be returned, in sorted order. If Some, then only the top fetch rows will be returned. This can reduce the memory pressure required by the sort operation since rows that are not going to be included can be dropped.

Source

pub fn input(&self) -> &Arc<dyn ExecutionPlan>

Input schema

Source

pub fn expr(&self) -> &LexOrdering

Sort expressions

Source

pub fn fetch(&self) -> Option<usize>

If Some(fetch), limits output to only the first “fetch” items

Source

pub fn common_prefix_length(&self) -> usize

Common prefix length

Trait Implementations§

Source§

impl Clone for PartialSortExec

Source§

fn clone(&self) -> PartialSortExec

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PartialSortExec

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl DisplayAs for PartialSortExec

Source§

fn fmt_as(&self, t: DisplayFormatType, f: &mut Formatter<'_>) -> Result

Format according to DisplayFormatType, used when verbose representation looks different from the default one Read more
Source§

impl ExecutionPlan for PartialSortExec

Source§

fn name(&self) -> &'static str

Short name for the ExecutionPlan, such as ‘DataSourceExec’. Read more
Source§

fn properties(&self) -> &Arc<PlanProperties>

Return properties of the output of the ExecutionPlan, such as output ordering(s), partitioning information etc. Read more
Source§

fn fetch(&self) -> Option<usize>

Gets the fetch count for the operator, None means there is no fetch.
Source§

fn required_input_distribution(&self) -> Vec<Distribution>

👎Deprecated since 55.0.0:

Use input_distribution_requirements

Specifies simple per-child input distribution requirements. Read more
Source§

fn input_distribution_requirements(&self) -> InputDistributionRequirements

Specifies the input distribution requirements for this plan. Read more
Source§

fn benefits_from_input_partitioning(&self) -> Vec<bool>

Specifies whether the ExecutionPlan benefits from increased parallelization at its input for each child. Read more
Source§

fn children(&self) -> Vec<&Arc<dyn ExecutionPlan>>

Get a list of children ExecutionPlans that act as inputs to this plan. The returned list will be empty for leaf nodes such as scans, will contain a single value for unary nodes, or two values for binary nodes (such as joins).
Source§

fn apply_expressions( &self, f: &mut dyn FnMut(&Arc<dyn PhysicalExpr>) -> Result<TreeNodeRecursion>, ) -> Result<TreeNodeRecursion>

Apply a closure f to each root expression that this node owns and uses during execution, either by evaluating it or updating it dynamically. Read more
Source§

fn replace_children( self: Arc<Self>, children: Vec<Arc<dyn ExecutionPlan>>, options: ReplaceChildrenOptions, ) -> Result<Arc<dyn ExecutionPlan>>

Returns a clone of the existing plan with the children replaced, skipping recomputation of plan properties when the options indicate the new children’s properties are unchanged. Read more
Source§

fn with_new_children( self: Arc<Self>, children: Vec<Arc<dyn ExecutionPlan>>, ) -> Result<Arc<dyn ExecutionPlan>>

👎Deprecated since 55.0.0:

Use ExecutionPlan::replace_children with ReplaceChildrenOptions

Deprecated. Read more
Source§

fn with_new_children_and_same_properties( self: Arc<Self>, children: Vec<Arc<dyn ExecutionPlan>>, ) -> Result<Arc<dyn ExecutionPlan>>

👎Deprecated since 55.0.0:

Use ExecutionPlan::replace_children with ReplaceChildrenOptions

Deprecated. Implement ExecutionPlan::replace_children instead.
Source§

fn execute( &self, partition: usize, context: Arc<TaskContext>, ) -> Result<SendableRecordBatchStream>

Begin execution of partition, returning a Stream of RecordBatches. Read more
Source§

fn metrics(&self) -> Option<MetricsSet>

Return a snapshot of the set of Metrics for this ExecutionPlan. If no Metrics are available, return None. Read more
Source§

fn child_stats_requests(&self, partition: Option<usize>) -> Vec<ChildStats>

Returns, per child, which statistics the StatisticsContext should resolve before calling Self::statistics_from_inputs. Read more
Source§

fn statistics_from_inputs( &self, input_stats: &[Arc<Statistics>], _args: &StatisticsArgs, ) -> Result<Arc<Statistics>>

Returns statistics for a specific partition of this ExecutionPlan node, given pre-computed child statistics. Read more
Source§

fn static_name() -> &'static str
where Self: Sized,

Short name for the ExecutionPlan, such as ‘DataSourceExec’. Like name but can be called without an instance.
Source§

fn downcast_delegate(&self) -> Option<&dyn ExecutionPlan>

Returns the plan that provides this plan’s public ExecutionPlan downcast identity. Read more
Source§

fn schema(&self) -> SchemaRef

Get the schema for this execution plan
Source§

fn check_invariants(&self, check: InvariantLevel) -> Result<()>

Returns an error if this individual node does not conform to its invariants. These invariants are typically only checked in debug mode. Read more
Source§

fn dynamic_expressions_produced(&self) -> Vec<Arc<dyn PhysicalExpr>>

Returns the dynamic expressions produced by this plan node. Read more
Source§

fn required_input_ordering(&self) -> Vec<Option<OrderingRequirements>>

Specifies the ordering required for all of the children of this ExecutionPlan. Read more
Source§

fn maintains_input_order(&self) -> Vec<bool>

Returns false if this ExecutionPlan’s implementation may reorder rows within or between partitions. Read more
Source§

fn reset_state(self: Arc<Self>) -> Result<Arc<dyn ExecutionPlan>>

Reset any internal state within this ExecutionPlan. Read more
Source§

fn repartitioned( &self, _target_partitions: usize, _config: &ConfigOptions, ) -> Result<Option<Arc<dyn ExecutionPlan>>>

If supported, attempt to increase the partitioning of this ExecutionPlan to produce target_partitions partitions. Read more
Source§

fn partition_statistics( &self, partition: Option<usize>, ) -> Result<Arc<Statistics>>

👎Deprecated since 55.0.0:

Use StatisticsContext::compute instead

Returns statistics for a specific partition of this ExecutionPlan node. Read more
Source§

fn supports_limit_pushdown(&self) -> bool

Returns true if a limit can be safely pushed down through this ExecutionPlan node. Read more
Source§

fn with_fetch(&self, _limit: Option<usize>) -> Option<Arc<dyn ExecutionPlan>>

Returns a fetching variant of this ExecutionPlan node, if it supports fetch limits. Returns None otherwise. Read more
Source§

fn cardinality_effect(&self) -> CardinalityEffect

Gets the effect on cardinality, if known
Source§

fn try_swapping_with_projection( &self, _projection: &ProjectionExec, ) -> Result<Option<Arc<dyn ExecutionPlan>>>

Attempts to push down the given projection into the input of this ExecutionPlan. Read more
Source§

fn gather_filters_for_pushdown( &self, _phase: FilterPushdownPhase, parent_filters: Vec<Arc<dyn PhysicalExpr>>, _config: &ConfigOptions, ) -> Result<FilterDescription>

Collect filters that this node can push down to its children. Filters that are being pushed down from parents are passed in, and the node may generate additional filters to push down. For example, given the plan FilterExec -> HashJoinExec -> DataSourceExec, what will happen is that we recurse down the plan calling ExecutionPlan::gather_filters_for_pushdown: Read more
Source§

fn handle_child_pushdown_result( &self, _phase: FilterPushdownPhase, child_pushdown_result: ChildPushdownResult, _config: &ConfigOptions, ) -> Result<FilterPushdownPropagation<Arc<dyn ExecutionPlan>>>

Handle the result of a child pushdown. Read more
Source§

fn with_new_state( &self, _state: Arc<dyn Any + Send + Sync>, ) -> Option<Arc<dyn ExecutionPlan>>

Injects arbitrary run-time state into this execution plan, returning a new plan instance that incorporates that state if it is relevant to the concrete node implementation. Read more
Source§

fn try_pushdown_sort( &self, _order: &[PhysicalSortExpr], ) -> Result<SortOrderPushdownResult<Arc<dyn ExecutionPlan>>>

Try to push down sort ordering requirements to this node. Read more
Source§

fn with_preserve_order( &self, _preserve_order: bool, ) -> Option<Arc<dyn ExecutionPlan>>

Returns a variant of this ExecutionPlan that is aware of order-sensitivity. Read more
Source§

fn try_to_proto( &self, _ctx: &ExecutionPlanEncodeCtx<'_>, ) -> Result<Option<PhysicalPlanNode>>

Available on crate feature proto only.
Serialize this plan to its protobuf representation, if it knows how. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V