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 = crate::bind_type_introspection(
78 expression,
79 child.row_schema(),
80 evaluator.parameters(),
81 );
82 }
83 Self {
84 inner: crate::external_sort::ExternalSort::new(
85 child,
86 keys,
87 evaluator,
88 None,
89 work_mem_bytes,
90 ),
91 }
92 }
93
94 pub fn with_evaluator_and_keep(
95 child: Box<dyn PhysicalOperator + 'a>,
96 mut keys: Vec<SortKey>,
97 evaluator: SharedExpressionEvaluator<'a>,
98 keep: usize,
99 ) -> Self {
100 for key in &mut keys {
101 let expression = std::mem::replace(&mut key.expr, ScalarExpr::Literal(Value::Null));
102 key.expr = crate::bind_type_introspection(
103 expression,
104 child.row_schema(),
105 evaluator.parameters(),
106 );
107 }
108 Self {
109 inner: crate::external_sort::ExternalSort::new(
110 child,
111 keys,
112 evaluator,
113 Some(keep),
114 DEFAULT_SORT_WORK_MEM_BYTES,
115 ),
116 }
117 }
118}
119
120pub fn compare_sort_key_values(keys: &[SortKey], av: &[Value], bv: &[Value]) -> std::cmp::Ordering {
124 compare_sort_key_values_by(keys, |index| (&av[index], &bv[index]))
125}
126
127pub(crate) fn compare_sort_key_values_by<'a>(
128 keys: &[SortKey],
129 mut values: impl FnMut(usize) -> (&'a Value, &'a Value),
130) -> std::cmp::Ordering {
131 use std::cmp::Ordering;
132 for (i, k) in keys.iter().enumerate() {
133 let (a, b) = values(i);
134 let a_null = matches!(a, Value::Null);
135 let b_null = matches!(b, Value::Null);
136 let nulls_first = k.nulls_first.unwrap_or(k.descending);
137 if a_null || b_null {
138 let null_cmp = if a_null == b_null {
139 Ordering::Equal
140 } else if a_null {
141 if nulls_first {
142 Ordering::Less
143 } else {
144 Ordering::Greater
145 }
146 } else if nulls_first {
147 Ordering::Greater
148 } else {
149 Ordering::Less
150 };
151 if null_cmp != Ordering::Equal {
152 return null_cmp;
153 }
154 continue;
155 }
156 let ord = compare_values(a, b);
157 let ord = if k.descending { ord.reverse() } else { ord };
158 if ord != Ordering::Equal {
159 return ord;
160 }
161 }
162 Ordering::Equal
163}
164
165pub(super) fn compare_values(a: &Value, b: &Value) -> std::cmp::Ordering {
166 use std::cmp::Ordering::*;
167 match (a, b) {
168 (Value::Null, Value::Null) => Equal,
169 (Value::Null, _) => Less,
170 (_, Value::Null) => Greater,
171 (Value::Temporal(x), Value::Str(y)) => x
172 .parse_same_kind(y)
173 .map_or_else(|| a.cmp(b), |parsed| x.cmp(&parsed)),
174 (Value::Str(x), Value::Temporal(y)) => y
175 .parse_same_kind(x)
176 .map_or_else(|| a.cmp(b), |parsed| parsed.cmp(y)),
177 _ => a.cmp(b),
178 }
179}
180
181impl PhysicalOperator for Sort<'_> {
182 fn row_schema(&self) -> &super::RowSchema {
183 self.inner.row_schema()
184 }
185
186 fn output_ordering(&self) -> &[crate::PhysicalOrder] {
187 self.inner.output_ordering()
188 }
189
190 fn open(&mut self) -> ExecResult<()> {
191 self.inner.open()
192 }
193
194 fn next(&mut self) -> ExecResult<Option<Batch>> {
195 self.inner.next()
196 }
197
198 fn close(&mut self) -> ExecResult<()> {
199 self.inner.close()
200 }
201}
202
203