MCPcopy Create free account
hub / github.com/apache/datafusion / accumulator

Method accumulator

datafusion/functions-aggregate/src/array_agg.rs:168–225  ·  view source on GitHub ↗
(&self, acc_args: AccumulatorArgs)

Source from the content-addressed store, hash-verified

166 }
167
168 fn accumulator(&self, acc_args: AccumulatorArgs) -> Result<Box<dyn Accumulator>> {
169 let field = &acc_args.expr_fields[0];
170 let data_type = field.data_type();
171 let ignore_nulls = acc_args.ignore_nulls && field.is_nullable();
172
173 if acc_args.is_distinct {
174 // Limitation similar to Postgres. The aggregation function can only mix
175 // DISTINCT and ORDER BY if all the expressions in the ORDER BY appear
176 // also in the arguments of the function. This implies that if the
177 // aggregation function only accepts one argument, only one argument
178 // can be used in the ORDER BY, For example:
179 //
180 // ARRAY_AGG(DISTINCT col)
181 //
182 // can only be mixed with an ORDER BY if the order expression is "col".
183 //
184 // ARRAY_AGG(DISTINCT col ORDER BY col) <- Valid
185 // ARRAY_AGG(DISTINCT concat(col, '') ORDER BY concat(col, '')) <- Valid
186 // ARRAY_AGG(DISTINCT col ORDER BY other_col) <- Invalid
187 // ARRAY_AGG(DISTINCT col ORDER BY concat(col, '')) <- Invalid
188 let sort_option = match acc_args.order_bys {
189 [single] if single.expr.eq(&acc_args.exprs[0]) => Some(single.options),
190 [] => None,
191 _ => {
192 return exec_err!(
193 "In an aggregate with DISTINCT, ORDER BY expressions must appear in argument list"
194 );
195 }
196 };
197 return Ok(Box::new(DistinctArrayAggAccumulator::try_new(
198 data_type,
199 sort_option,
200 ignore_nulls,
201 )?));
202 }
203
204 let Some(ordering) = LexOrdering::new(acc_args.order_bys.to_vec()) else {
205 return Ok(Box::new(ArrayAggAccumulator::try_new(
206 data_type,
207 ignore_nulls,
208 )?));
209 };
210
211 let ordering_dtypes = ordering
212 .iter()
213 .map(|e| e.expr.data_type(acc_args.schema))
214 .collect::<Result<Vec<_>>>()?;
215
216 OrderSensitiveArrayAggAccumulator::try_new(
217 data_type,
218 &ordering_dtypes,
219 ordering,
220 self.is_input_pre_ordered,
221 acc_args.is_reversed,
222 ignore_nulls,
223 )
224 .map(|acc| Box::new(acc) as _)
225 }

Callers 1

buildMethod · 0.45

Calls 7

newFunction · 0.85
to_vecMethod · 0.80
data_typeMethod · 0.45
is_nullableMethod · 0.45
eqMethod · 0.45
mapMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected