mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 02:53:51 +08:00
Inlineable functions used to be slow to plan, because the query preprocessing function could not find the relations inside the functions, as they haven't been inlined yet at that point. This commit adds a separate check in the get_relation_info_hook to optimize pruning of hypertables.
76 lines
2.1 KiB
SQL
76 lines
2.1 KiB
SQL
-- This file and its contents are licensed under the Apache License 2.0.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-APACHE for a copy of the license.
|
|
|
|
-- test hypertable classification when query is in an inlineable function
|
|
|
|
\set PREFIX 'EXPLAIN (costs off)'
|
|
|
|
CREATE TABLE test (a int, b bigint NOT NULL);
|
|
SELECT create_hypertable('public.test', 'b', chunk_time_interval=>10);
|
|
INSERT INTO test SELECT i, i FROM generate_series(1, 20) i;
|
|
|
|
CREATE OR REPLACE FUNCTION test_f(_ts bigint)
|
|
RETURNS SETOF test LANGUAGE SQL STABLE
|
|
as $f$
|
|
SELECT DISTINCT ON (a) * FROM test WHERE b >= _ts AND b <= _ts + 2
|
|
$f$;
|
|
|
|
-- plans must be the same in both cases
|
|
-- specifically, the first plan should not contain the parent hypertable
|
|
-- as that is a sign the pruning was not done successfully
|
|
:PREFIX SELECT * FROM test_f(5);
|
|
|
|
:PREFIX SELECT DISTINCT ON (a) * FROM test WHERE b >= 5 AND b <= 5 + 2;
|
|
|
|
|
|
-- test with FOR UPDATE
|
|
CREATE OR REPLACE FUNCTION test_f(_ts bigint)
|
|
RETURNS SETOF test LANGUAGE SQL STABLE
|
|
as $f$
|
|
SELECT * FROM test WHERE b >= _ts AND b <= _ts + 2 FOR UPDATE
|
|
$f$;
|
|
|
|
|
|
-- pruning should not be done by TimescaleDb in this case
|
|
-- specifically, the parent hypertable must exist in the output plan
|
|
:PREFIX SELECT * FROM test_f(5);
|
|
|
|
:PREFIX SELECT * FROM test WHERE b >= 5 AND b <= 5 + 2 FOR UPDATE;
|
|
|
|
-- test with CTE
|
|
-- these cases are just to make sure we're everything is alright with
|
|
-- the way we identify hypertables to prune chunks - we abuse ctename
|
|
-- for this purpose. So double-check if we're not breaking plans
|
|
-- with CTEs here.
|
|
CREATE OR REPLACE FUNCTION test_f(_ts bigint)
|
|
RETURNS SETOF test LANGUAGE SQL STABLE
|
|
as $f$
|
|
WITH ct AS MATERIALIZED (
|
|
SELECT DISTINCT ON (a) * FROM test WHERE b >= _ts AND b <= _ts + 2
|
|
)
|
|
SELECT * FROM ct
|
|
$f$;
|
|
|
|
:PREFIX SELECT * FROM test_f(5);
|
|
|
|
:PREFIX
|
|
WITH ct AS MATERIALIZED (
|
|
SELECT DISTINCT ON (a) * FROM test WHERE b >= 5 AND b <= 5 + 2
|
|
)
|
|
SELECT * FROM ct;
|
|
|
|
-- CTE within CTE
|
|
:PREFIX
|
|
WITH ct AS MATERIALIZED (
|
|
SELECT * FROM test_f(5)
|
|
)
|
|
SELECT * FROM ct;
|
|
|
|
-- CTE within NO MATERIALIZED CTE
|
|
:PREFIX
|
|
WITH ct AS NOT MATERIALIZED (
|
|
SELECT * FROM test_f(5)
|
|
)
|
|
SELECT * FROM ct;
|