Skip to content

Commit

Permalink
added approx_percentile_array, arrow fn is broken
Browse files Browse the repository at this point in the history
  • Loading branch information
thatzopoulos committed Nov 15, 2022
1 parent 619563c commit 35a9ff7
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 5 deletions.
25 changes: 24 additions & 1 deletion extension/src/accessors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,4 +545,27 @@ pub mod toolkit_experimental {
}
}
}
}

pg_type! {
#[derive(Debug)]
struct AccessorPercentileArray<'input> {
len: u64,
percentile: [f64; self.len],
}
}

ron_inout_funcs!(AccessorPercentileArray);

#[pg_extern(immutable, parallel_safe, name = "percentiles")]
pub fn accessor_percentiles(unit: Vec<f64>) -> AccessorPercentileArray<'static> {
unsafe {
flatten! {
AccessorPercentileArray{
len: unit.len().try_into().unwrap(),
percentile: unit.into(),
}
}
}
}
} //calling accessor with array of floats
// select percentile_agg(...) -> percentiles([0.1, 0.25, .05]) from ...;
2 changes: 1 addition & 1 deletion extension/src/aggregate_builder_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ mod tests {
toolkit_experimental.parallel_anything_deserialize_fn_outer,\
toolkit_experimental.parallel_anything_combine_fn_outer\
)"
);
);
});
}

Expand Down
120 changes: 117 additions & 3 deletions extension/src/uddsketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use uddsketch::{SketchHashKey, UDDSketch as UddSketchInternal};

use crate::{
accessors::{
AccessorApproxPercentile, AccessorApproxPercentileRank, AccessorError, AccessorMean,
AccessorNumVals,
toolkit_experimental, AccessorApproxPercentile, AccessorApproxPercentileRank,
AccessorError, AccessorMean, AccessorNumVals,
},
aggregate_utils::in_aggregate_context,
flatten,
Expand Down Expand Up @@ -74,7 +74,6 @@ pub fn percentile_agg_trans_inner(
let default_max_error = PERCENTILE_AGG_DEFAULT_ERROR;
uddsketch_trans_inner(state, default_size as _, default_max_error, value, fcinfo)
}

// PG function for merging sketches.
#[pg_extern(immutable, parallel_safe)]
pub fn uddsketch_combine(
Expand Down Expand Up @@ -582,6 +581,46 @@ pub fn uddsketch_approx_percentile<'a>(percentile: f64, sketch: UddSketch<'a>) -
)
}

// #[pg_operator(immutable, schema = "toolkit_experimental", parallel_safe)]
// #[opname(->)]
// pub fn arrow_uddsketch_approx_percentile_array<'a>(
// sketch: UddSketch<'a>,
// percentiles: toolkit_experimental::AccessorPercentileArray<'a>,
// ) -> Vec<f64> {
// approx_percentile_slice(percentiles.percentile.as_slice(), sketch)
// }

// Approximate the value at the given approx_percentile (0.0-1.0) for each entry in an array
#[pg_extern(
immutable,
schema = "toolkit_experimental",
parallel_safe,
name = "approx_percentile_array"
)]
pub fn uddsketch_approx_percentile_array<'a>(
percentiles: Vec<f64>,
sketch: UddSketch<'a>,
) -> Vec<f64> {
approx_percentile_slice(&percentiles, sketch)
}

fn approx_percentile_slice<'a, 'b>(
percentiles: impl IntoIterator<Item = &'b f64>,
sketch: UddSketch<'a>,
) -> Vec<f64> {
let mut results = Vec::new();
for percentile in percentiles {
results.push(uddsketch::estimate_quantile(
*percentile,
sketch.alpha,
uddsketch::gamma(sketch.alpha),
sketch.count,
sketch.keys().zip(sketch.counts()),
))
}
results
}

#[pg_operator(immutable, parallel_safe)]
#[opname(->)]
pub fn arrow_uddsketch_approx_rank<'a>(
Expand Down Expand Up @@ -920,6 +959,81 @@ mod tests {
pct_eql(test_value.unwrap(), 9.0, test_error.unwrap());
});
}
#[pg_test]
fn test_approx_percentile_array() {
Spi::execute(|client| {
client.select(
"CREATE TABLE paa_test (device INTEGER, value DOUBLE PRECISION)",
None,
None,
);
client.select("INSERT INTO paa_test SELECT dev, dev - v FROM generate_series(1,10) dev, generate_series(0, 1.0, 0.01) v", None, None);

let sanity = client
.select("SELECT COUNT(*) FROM paa_test", None, None)
.first()
.get_one::<i32>();
assert_eq!(Some(1010), sanity);

client.select(
"CREATE VIEW uddsketch_test AS \
SELECT uddsketch(200, 0.001, value) as approx \
FROM paa_test ",
None,
None,
);

client.select(
"CREATE VIEW percentile_agg AS \
SELECT percentile_agg(value) as approx \
FROM paa_test",
None,
None,
);

let (value, error) = client
.select(
"SELECT \
toolkit_experimental.approx_percentile_array(array[0.9,0.5,0.1], approx), \
error(approx) \
FROM uddsketch_test",
None,
None,
)
.first()
.get_two::<Vec<f64>, f64>();

let (test_value, test_error) = client
.select(
"SELECT \
toolkit_experimental.approx_percentile_array(array[0.9,0.5,0.1], approx), \
error(approx) \
FROM percentile_agg",
None,
None,
)
.first()
.get_two::<Vec<f64>, f64>();

assert!(
test_value
.as_ref()
.unwrap()
.iter()
.zip(value.unwrap())
.all(|(a, b)| { (a - b).abs() < 0.0001 }),
"Some Float value differs from expected by more than {}",
0.0001
);

apx_eql(test_error.unwrap(), error.unwrap(), 0.000001);
assert!(test_value
.unwrap()
.iter()
.zip(vec![9.0, 5.0, 0.984])
.all(|(a, b)| { matches!(pct_eql(a.clone(), b, test_error.unwrap()), ()) }));
});
}

#[pg_test]
fn uddsketch_io_test() {
Expand Down

0 comments on commit 35a9ff7

Please sign in to comment.