timeseries-hoarder/lib/timeseries/hoarder/sql/manyagg.sql

89 lines
No EOL
2.7 KiB
PL/PgSQL

CREATE OR REPLACE FUNCTION public.aggregate_autoselect(
root_table character varying,
data_interval interval,
filter_query character varying,
agg_pairs jsonb,
metric_statement character varying DEFAULT 'tags',
agg_basename character varying DEFAULT NULL,
agg_schema character varying DEFAULT 'public',
time_column character varying DEFAULT 'time')
RETURNS SETOF RECORD
LANGUAGE 'plpgsql'
STABLE
PARALLEL SAFE
AS $BODY$
DECLARE
selected_table record;
selected_column character varying;
selected_aggregator character varying;
BEGIN
agg_basename := coalesce(agg_basename, root_table);
WITH table_selection AS (
SELECT table_name, column_name,
coalesce(substring(table_name, agg_basename || '_\"%\"', '\'), '0')::interval AS table_interval
FROM information_schema.columns
WHERE table_schema=agg_schema
AND ((table_name = root_table) OR (table_name LIKE (agg_basename || '_%')))
AND agg_pairs?column_name
)
SELECT table_name, column_name
INTO selected_table
FROM table_selection
WHERE table_interval <= data_interval
ORDER BY table_interval DESC
LIMIT 1;
IF NOT FOUND THEN
RETURN;
END IF;
selected_aggregator := agg_pairs->>selected_table.column_name;
RAISE NOTICE 'Using table %, column %, aggreagtor %', selected_table.table_name, selected_table.column_name, selected_aggregator;
RETURN QUERY EXECUTE format($qry$
SELECT time_bucket($1, %I::timestamptz) AS time, (%s)::text AS metric, (%s) AS "value"
FROM %I.%I
WHERE %s
GROUP BY 1, (%s)::text
ORDER BY time
$qry$, time_column, metric_statement, selected_aggregator,
agg_schema, selected_table.table_name,
filter_query,
metric_statement)
USING data_interval;
END;
$BODY$;
CREATE OR REPLACE FUNCTION public.percentile_autoselect(
root_table character varying,
data_interval interval,
percentiles double precision[],
filter_query text,
metric_statement character varying DEFAULT 'tags',
agg_basename character varying DEFAULT NULL,
agg_schema character varying DEFAULT 'public',
time_column character varying DEFAULT 'time')
RETURNS TABLE ("time" TIMESTAMPTZ, "metric" TEXT, "percentile" DOUBLE PRECISION, "value" DOUBLE PRECISION)
LANGUAGE 'plpgsql'
STABLE
PARALLEL SAFE
AS $body$
DECLARE
BEGIN
RETURN QUERY
WITH ts_data AS (
SELECT * FROM aggregate_autoselect(root_table, data_interval, filter_query,
$${"value": "tdigest(10, value)", "tdigest": "rollup(tdigest)"}$$::jsonb,
metric_statement, agg_basename, agg_schema, time_column)
r("time" TIMESTAMPTZ, metric TEXT, value tdigest)
)
SELECT ts_data."time", ts_data.metric, up.percentile, approx_percentile(up.percentile, ts_data.value) AS "value"
FROM ts_data
CROSS JOIN unnest(percentiles) AS up(percentile)
ORDER BY ts_data."time";
END;
$body$;