cr_bucket_using_width_bucket.sql

This page documents the preview version (v2.23). Preview includes features under active development and is for development and testing only. For production, use the stable version (v2024.1). To learn more, see Versioning.

Save this script as cr_bucket_using_width_bucket.sql.

-- This approach subtracts a tiny value, epsilon, from the input value
-- to change "width_bucket()"'s "closed-open" interval bucket semantics to
-- the required "open-closed" interval bucket semantics.
--
-- You might consider this to be a rather obscure and possibly risky trick.
-- However, this implementation of "bucket()" does pass the rigorous
-- acceptance test.

create or replace function bucket(
  val          in double precision,
  lower_bound  in double precision default 0,
  upper_bound  in double precision default 1,
  no_of_values in int              default 10)
  returns int
  language plpgsql
as $body$
begin
  declare
    one     constant int              := 1;
    zero    constant double precision := 0;
    epsilon constant double precision := 0.0000000001;

    result constant int not null :=
      case
        when val between zero and epsilon
          then one
        else
          width_bucket((val - epsilon), lower_bound, upper_bound, no_of_values)
      end;
  begin
    assert
      (result between one and no_of_values),
    'bucket():'||
    ' val '||val||
    ' must be between lower_bound '||lower_bound||
    ' and upper_bound '||upper_bound;

    return result;
  end;
end;
$body$;