uqa_execution/relational/
sort.rs1use super::{
10 Batch, DefaultExpressionEvaluator, ExecResult, PhysicalOperator, SQLParam, ScalarExpr,
11 SharedExpressionEvaluator, Value,
12};
13
14#[derive(Debug, Clone)]
15pub struct SortKey {
16 pub expr: ScalarExpr,
17 pub descending: bool,
18 pub nulls_first: Option<bool>,
22}
23
24const DEFAULT_SORT_WORK_MEM_BYTES: usize = 64 * 1024 * 1024;
28
29pub struct Sort<'a> {
30 inner: crate::external_sort::ExternalSort<'a>,
31}
32
33impl Sort<'static> {
34 pub fn new(
35 child: Box<dyn PhysicalOperator>,
36 keys: Vec<SortKey>,
37 params: Vec<SQLParam>,
38 ) -> Self {
39 Self::with_evaluator(child, keys, DefaultExpressionEvaluator::shared(params))
40 }
41
42 pub fn with_keep(
46 child: Box<dyn PhysicalOperator>,
47 keys: Vec<SortKey>,
48 params: Vec<SQLParam>,
49 keep: usize,
50 ) -> Self {
51 Self::with_evaluator_and_keep(
52 child,
53 keys,
54 DefaultExpressionEvaluator::shared(params),
55 keep,
56 )
57 }
58}
59
60impl<'a> Sort<'a> {
61 pub fn with_evaluator(
62 child: Box<dyn PhysicalOperator + 'a>,
63 keys: Vec<SortKey>,
64 evaluator: SharedExpressionEvaluator<'a>,
65 ) -> Self {
66 Self::with_evaluator_and_work_mem(child, keys, evaluator, DEFAULT_SORT_WORK_MEM_BYTES)
67 }
68
69 pub fn with_evaluator_and_work_mem(
70 child: Box<dyn PhysicalOperator + 'a>,
71 mut keys: Vec<SortKey>,
72 evaluator: SharedExpressionEvaluator<'a>,
73 work_mem_bytes: usize,
74 ) -> Self {
75 for key in &mut keys {
76 let expression = std::mem::replace(&mut key.expr, ScalarExpr::Literal(Value::Null));
77 key.expr = evaluator.bind_type_introspection(expression, child.row_schema());
78 }
79 Self {
80 inner: crate::external_sort::ExternalSort::new(
81 child,
82 keys,
83 evaluator,
84 None,
85 work_mem_bytes,
86 ),
87 }
88 }
89
90 pub fn with_evaluator_and_keep(
91 child: Box<dyn PhysicalOperator + 'a>,
92 mut keys: Vec<SortKey>,
93 evaluator: SharedExpressionEvaluator<'a>,
94 keep: usize,
95 ) -> Self {
96 for key in &mut keys {
97 let expression = std::mem::replace(&mut key.expr, ScalarExpr::Literal(Value::Null));
98 key.expr = evaluator.bind_type_introspection(expression, child.row_schema());
99 }
100 Self {
101 inner: crate::external_sort::ExternalSort::new(
102 child,
103 keys,
104 evaluator,
105 Some(keep),
106 DEFAULT_SORT_WORK_MEM_BYTES,
107 ),
108 }
109 }
110}
111
112pub fn compare_sort_key_values(keys: &[SortKey], av: &[Value], bv: &[Value]) -> std::cmp::Ordering {
116 compare_sort_key_values_by(keys, |index| (&av[index], &bv[index]))
117}
118
119pub(crate) fn compare_sort_key_values_by<'a>(
120 keys: &[SortKey],
121 mut values: impl FnMut(usize) -> (&'a Value, &'a Value),
122) -> std::cmp::Ordering {
123 use std::cmp::Ordering;
124 for (i, k) in keys.iter().enumerate() {
125 let (a, b) = values(i);
126 let a_null = matches!(a, Value::Null);
127 let b_null = matches!(b, Value::Null);
128 let nulls_first = k.nulls_first.unwrap_or(k.descending);
129 if a_null || b_null {
130 let null_cmp = if a_null == b_null {
131 Ordering::Equal
132 } else if a_null {
133 if nulls_first {
134 Ordering::Less
135 } else {
136 Ordering::Greater
137 }
138 } else if nulls_first {
139 Ordering::Greater
140 } else {
141 Ordering::Less
142 };
143 if null_cmp != Ordering::Equal {
144 return null_cmp;
145 }
146 continue;
147 }
148 let ord = compare_values(a, b);
149 let ord = if k.descending { ord.reverse() } else { ord };
150 if ord != Ordering::Equal {
151 return ord;
152 }
153 }
154 Ordering::Equal
155}
156
157pub(super) fn compare_values(a: &Value, b: &Value) -> std::cmp::Ordering {
158 use std::cmp::Ordering::*;
159 match (a, b) {
160 (Value::Null, Value::Null) => Equal,
161 (Value::Null, _) => Less,
162 (_, Value::Null) => Greater,
163 (Value::Temporal(x), Value::Str(y)) => x
164 .parse_same_kind(y)
165 .map_or_else(|| a.cmp(b), |parsed| x.cmp(&parsed)),
166 (Value::Str(x), Value::Temporal(y)) => y
167 .parse_same_kind(x)
168 .map_or_else(|| a.cmp(b), |parsed| parsed.cmp(y)),
169 _ => a.cmp(b),
170 }
171}
172
173impl PhysicalOperator for Sort<'_> {
174 fn row_schema(&self) -> &super::RowSchema {
175 self.inner.row_schema()
176 }
177
178 fn output_ordering(&self) -> &[crate::PhysicalOrder] {
179 self.inner.output_ordering()
180 }
181
182 fn backward_scan_support(&self) -> crate::BackwardScanSupport {
183 crate::BackwardScanSupport::Materialize
184 }
185
186 fn open(&mut self) -> ExecResult<()> {
187 self.inner.open()
188 }
189
190 fn next(&mut self) -> ExecResult<Option<Batch>> {
191 self.inner.next()
192 }
193
194 fn close(&mut self) -> ExecResult<()> {
195 self.inner.close()
196 }
197}
198
199