timescaledb/test/sql/plan_hypertable_inline.sql
Floris van Nee 5c6940d734 Add support for fast pruning of inlined functions
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.
2020-06-04 09:20:58 +02:00

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;