@@ -1323,6 +1323,42 @@ t_stree::update_agg_table(
13231323
13241324 dst->set_scalar (dst_ridx, new_value);
13251325 } break ;
1326+ case AGGTYPE_Q1: {
1327+ old_value.set (dst->get_scalar (dst_ridx));
1328+ auto pkeys = get_pkeys (nidx);
1329+ new_value.set (
1330+ reduce_from_gstate<
1331+ std::function<t_tscalar (std::vector<t_tscalar>&)>>(
1332+ gstate,
1333+ expression_master_table,
1334+ spec.get_dependencies ()[0 ].name (),
1335+ pkeys,
1336+ [&](std::vector<t_tscalar>& values) {
1337+ return get_aggregate_median (values, 0.25 );
1338+ }
1339+ )
1340+ );
1341+
1342+ dst->set_scalar (dst_ridx, new_value);
1343+ } break ;
1344+ case AGGTYPE_Q3: {
1345+ old_value.set (dst->get_scalar (dst_ridx));
1346+ auto pkeys = get_pkeys (nidx);
1347+ new_value.set (
1348+ reduce_from_gstate<
1349+ std::function<t_tscalar (std::vector<t_tscalar>&)>>(
1350+ gstate,
1351+ expression_master_table,
1352+ spec.get_dependencies ()[0 ].name (),
1353+ pkeys,
1354+ [&](std::vector<t_tscalar>& values) {
1355+ return get_aggregate_median (values, 0.75 );
1356+ }
1357+ )
1358+ );
1359+
1360+ dst->set_scalar (dst_ridx, new_value);
1361+ } break ;
13261362 case AGGTYPE_MEDIAN: {
13271363 old_value.set (dst->get_scalar (dst_ridx));
13281364 auto pkeys = get_pkeys (nidx);
@@ -1335,7 +1371,7 @@ t_stree::update_agg_table(
13351371 spec.get_dependencies ()[0 ].name (),
13361372 pkeys,
13371373 [&](std::vector<t_tscalar>& values) {
1338- return get_aggregate_median (values);
1374+ return get_aggregate_median (values, 0.5 );
13391375 }
13401376 )
13411377 );
@@ -2326,26 +2362,31 @@ t_stree::get_aggregate(t_index idx, t_index aggnum) const {
23262362}
23272363
23282364t_tscalar
2329- t_stree::get_aggregate_median (std::vector<t_tscalar>& values) const {
2330- int size = values.size ();
2331- bool is_even_size = size % 2 == 0 ;
2332-
2365+ t_stree::get_aggregate_median (std::vector<t_tscalar>& values, float n ) const {
2366+ const auto size = values.size ();
2367+ const float raw_size = static_cast < float >( size) * n ;
2368+ bool is_even_size = fabsf ( roundf (raw_size) - raw_size) <= 0.00001 ;
23332369 if (size == 0 ) {
23342370 return {};
23352371 }
2372+
23362373 if (size == 1 ) {
23372374 return values[0 ];
23382375 }
2376+
2377+ const auto split = static_cast <long >(raw_size);
23392378 if (is_even_size && values[0 ].is_floating_point ()) {
23402379 t_tscalar median_average;
2341- auto middle = values.begin () + (size / 2 ) ;
2380+ auto middle = values.begin () + split ;
23422381 nth_element (values.begin (), middle, values.end ());
23432382 median_average.set (
23442383 (*middle + *(middle - 1 )) / static_cast <t_tscalar>(2 )
23452384 );
2385+
23462386 return median_average;
23472387 }
2348- auto middle = values.begin () + (size / 2 );
2388+
2389+ auto middle = values.begin () + split;
23492390 std::nth_element (values.begin (), middle, values.end ());
23502391 return *middle;
23512392}
0 commit comments