@ -652,10 +652,11 @@ select first_value(max(x)) over (), y
QUERY PLAN
---------------------------------------------
WindowAgg
Window: w1 AS ()
-> HashAggregate
Group Key: (tenk1.ten + tenk1.four)
-> Seq Scan on tenk1
(4 rows)
(5 rows)
-- window functions returning pass-by-ref values from different rows
select x, lag(x, 1) over (order by x), lead(x, 3) over (order by x)
@ -3538,13 +3539,14 @@ select f1, sum(f1) over (partition by f1 order by f2
range between 1 preceding and 1 following)
from t1 where f1 = f2;
QUERY PLAN
---------------------------------
-------------------------------------------------------------------------------------------------------------
WindowAgg
Window: w1 AS (PARTITION BY f1 ORDER BY f2 RANGE BETWEEN '1'::bigint PRECEDING AND '1'::bigint FOLLOWING)
-> Sort
Sort Key: f1
-> Seq Scan on t1
Filter: (f1 = f2)
(5 rows)
(6 rows)
select f1, sum(f1) over (partition by f1 order by f2
range between 1 preceding and 1 following)
@ -3584,13 +3586,14 @@ select f1, sum(f1) over (partition by f1 order by f2
groups between 1 preceding and 1 following)
from t1 where f1 = f2;
QUERY PLAN
---------------------------------
--------------------------------------------------------------------------------------------------------------
WindowAgg
Window: w1 AS (PARTITION BY f1 ORDER BY f2 GROUPS BETWEEN '1'::bigint PRECEDING AND '1'::bigint FOLLOWING)
-> Sort
Sort Key: f1
-> Seq Scan on t1
Filter: (f1 = f2)
(5 rows)
(6 rows)
select f1, sum(f1) over (partition by f1 order by f2
groups between 1 preceding and 1 following)
@ -3712,12 +3715,13 @@ SELECT
CURRENT ROW AND UNBOUNDED FOLLOWING) cd
FROM empsalary;
QUERY PLAN
----------------------------------------
--------------------------------------------------------------------------------------
WindowAgg
Window: w1 AS (PARTITION BY depname ORDER BY enroll_date ROWS UNBOUNDED PRECEDING)
-> Sort
Sort Key: depname, enroll_date
-> Seq Scan on empsalary
(4 rows)
(5 rows)
-- Ensure WindowFuncs which cannot support their WindowClause's frameOptions
-- being changed are untouched
@ -3732,17 +3736,19 @@ SELECT
CURRENT ROW AND CURRENT ROW) cnt
FROM empsalary;
QUERY PLAN
------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------
WindowAgg
Output: empno, depname, (row_number() OVER (?)), (rank() OVER (?)), count(*) OVER (?), enroll_date
Output: empno, depname, (row_number() OVER w1), (rank() OVER w1), count(*) OVER w2, enroll_date
Window: w2 AS (PARTITION BY empsalary.depname ORDER BY empsalary.enroll_date RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
-> WindowAgg
Output: depname, enroll_date, empno, row_number() OVER (?), rank() OVER (?)
Output: depname, enroll_date, empno, row_number() OVER w1, rank() OVER w1
Window: w1 AS (PARTITION BY empsalary.depname ORDER BY empsalary.enroll_date ROWS UNBOUNDED PRECEDING)
-> Sort
Output: depname, enroll_date, empno
Sort Key: empsalary.depname, empsalary.enroll_date
-> Seq Scan on pg_temp.empsalary
Output: depname, enroll_date, empno
(9 rows)
(11 rows)
-- Ensure the above query gives us the expected results
SELECT
@ -3778,15 +3784,17 @@ SELECT * FROM
FROM empsalary) emp
WHERE depname = 'sales';
QUERY PLAN
--------------------------------------------------------------------------
---------------------------------------------------------------------------------------
Subquery Scan on emp
-> WindowAgg
Window: w2 AS ()
-> WindowAgg
Window: w1 AS (PARTITION BY (((empsalary.depname)::text || 'A'::text)))
-> Sort
Sort Key: (((empsalary.depname)::text || 'A'::text))
-> Seq Scan on empsalary
Filter: ((depname)::text = 'sales'::text)
(7 rows)
(9 rows)
-- pushdown is unsafe because there's a PARTITION BY clause without depname:
EXPLAIN (COSTS OFF)
@ -3797,17 +3805,19 @@ SELECT * FROM
FROM empsalary) emp
WHERE depname = 'sales';
QUERY PLAN
-------------------------------------------------------
--------------------------------------------------------------------
Subquery Scan on emp
Filter: ((emp.depname)::text = 'sales'::text)
-> WindowAgg
Window: w2 AS (PARTITION BY empsalary.enroll_date)
-> Sort
Sort Key: empsalary.enroll_date
-> WindowAgg
Window: w1 AS (PARTITION BY empsalary.depname)
-> Sort
Sort Key: empsalary.depname
-> Seq Scan on empsalary
(9 rows)
(11 rows)
-- Test window function run conditions are properly pushed down into the
-- WindowAgg
@ -3818,13 +3828,14 @@ SELECT * FROM
FROM empsalary) emp
WHERE rn < 3;
QUERY PLAN
----------------------------------------------
---------------------------------------------------------------------
WindowAgg
Run Condition: (row_number() OVER (?) < 3)
Window: w1 AS (ORDER BY empsalary.empno ROWS UNBOUNDED PRECEDING)
Run Condition: (row_number() OVER w1 < 3)
-> Sort
Sort Key: empsalary.empno
-> Seq Scan on empsalary
(5 rows)
(6 rows)
-- The following 3 statements should result the same result.
SELECT * FROM
@ -3869,13 +3880,14 @@ SELECT * FROM
FROM empsalary) emp
WHERE r <= 3;
QUERY PLAN
-----------------------------------------
----------------------------------------------------------------------
WindowAgg
Run Condition: (rank() OVER (?) <= 3)
Window: w1 AS (ORDER BY empsalary.salary ROWS UNBOUNDED PRECEDING)
Run Condition: (rank() OVER w1 <= 3)
-> Sort
Sort Key: empsalary.salary DESC
-> Seq Scan on empsalary
(5 rows)
(6 rows)
SELECT * FROM
(SELECT empno,
@ -3899,15 +3911,16 @@ SELECT * FROM
FROM empsalary) emp
WHERE dr = 1;
QUERY PLAN
-----------------------------------------------------
----------------------------------------------------------------------------
Subquery Scan on emp
Filter: (emp.dr = 1)
-> WindowAgg
Run Condition: (dense_rank() OVER (?) <= 1)
Window: w1 AS (ORDER BY empsalary.salary ROWS UNBOUNDED PRECEDING)
Run Condition: (dense_rank() OVER w1 <= 1)
-> Sort
Sort Key: empsalary.salary DESC
-> Seq Scan on empsalary
(7 rows)
(8 rows)
SELECT * FROM
(SELECT empno,
@ -3929,13 +3942,14 @@ SELECT * FROM
FROM empsalary) emp
WHERE c <= 3;
QUERY PLAN
-------------------------------------------
---------------------------------------------
WindowAgg
Run Condition: (count(*) OVER (?) <= 3)
Window: w1 AS (ORDER BY empsalary.salary)
Run Condition: (count(*) OVER w1 <= 3)
-> Sort
Sort Key: empsalary.salary DESC
-> Seq Scan on empsalary
(5 rows)
(6 rows)
SELECT * FROM
(SELECT empno,
@ -3958,13 +3972,14 @@ SELECT * FROM
FROM empsalary) emp
WHERE c <= 3;
QUERY PLAN
---------------------------------------------------------
--------------------------------------------------------
WindowAgg
Run Condition: (count(empsalary.empno) OVER (?) <= 3)
Window: w1 AS (ORDER BY empsalary.salary)
Run Condition: (count(empsalary.empno) OVER w1 <= 3)
-> Sort
Sort Key: empsalary.salary DESC
-> Seq Scan on empsalary
(5 rows)
(6 rows)
SELECT * FROM
(SELECT empno,
@ -3987,13 +4002,14 @@ SELECT * FROM
FROM empsalary) emp
WHERE c >= 3;
QUERY PLAN
-------------------------------------------
----------------------------------------------------------------------------------------------
WindowAgg
Run Condition: (count(*) OVER (?) >= 3)
Window: w1 AS (ORDER BY empsalary.salary ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
Run Condition: (count(*) OVER w1 >= 3)
-> Sort
Sort Key: empsalary.salary DESC
-> Seq Scan on empsalary
(5 rows)
(6 rows)
EXPLAIN (COSTS OFF)
SELECT * FROM
@ -4003,11 +4019,12 @@ SELECT * FROM
FROM empsalary) emp
WHERE 11 <= c;
QUERY PLAN
--------------------------------------------
-------------------------------------------
WindowAgg
Run Condition: (11 <= count(*) OVER (?))
Window: w1 AS ()
Run Condition: (11 <= count(*) OVER w1)
-> Seq Scan on empsalary
(3 rows)
(4 rows)
EXPLAIN (COSTS OFF)
SELECT * FROM
@ -4018,15 +4035,16 @@ SELECT * FROM
FROM empsalary) emp
WHERE dr = 1;
QUERY PLAN
-----------------------------------------------------
----------------------------------------------------
Subquery Scan on emp
Filter: (emp.dr = 1)
-> WindowAgg
Run Condition: (dense_rank() OVER (?) <= 1)
Window: w1 AS (ORDER BY empsalary.salary)
Run Condition: (dense_rank() OVER w1 <= 1)
-> Sort
Sort Key: empsalary.salary DESC
-> Seq Scan on empsalary
(7 rows)
(8 rows)
-- Ensure we get a run condition when there's a PARTITION BY clause
EXPLAIN (COSTS OFF)
@ -4037,13 +4055,14 @@ SELECT * FROM
FROM empsalary) emp
WHERE rn < 3;
QUERY PLAN
------------------------------------------------------
----------------------------------------------------------------------------------------------------
WindowAgg
Run Condition: (row_number() OVER (?) < 3)
Window: w1 AS (PARTITION BY empsalary.depname ORDER BY empsalary.empno ROWS UNBOUNDED PRECEDING)
Run Condition: (row_number() OVER w1 < 3)
-> Sort
Sort Key: empsalary.depname, empsalary.empno
-> Seq Scan on empsalary
(5 rows)
(6 rows)
-- and ensure we get the correct results from the above plan
SELECT * FROM
@ -4072,14 +4091,15 @@ SELECT empno, depname FROM
FROM empsalary) emp
WHERE rn < 3;
QUERY PLAN
------------------------------------------------------------
----------------------------------------------------------------------------------------------------------
Subquery Scan on emp
-> WindowAgg
Run Condition: (row_number() OVER (?) < 3)
Window: w1 AS (PARTITION BY empsalary.depname ORDER BY empsalary.empno ROWS UNBOUNDED PRECEDING)
Run Condition: (row_number() OVER w1 < 3)
-> Sort
Sort Key: empsalary.depname, empsalary.empno
-> Seq Scan on empsalary
(6 rows)
(7 rows)
-- likewise with count(empno) instead of row_number()
EXPLAIN (COSTS OFF)
@ -4091,13 +4111,14 @@ SELECT * FROM
FROM empsalary) emp
WHERE c <= 3;
QUERY PLAN
------------------------------------------------------------
----------------------------------------------------------------------------
WindowAgg
Run Condition: (count(empsalary.empno) OVER (?) <= 3)
Window: w1 AS (PARTITION BY empsalary.depname ORDER BY empsalary.salary)
Run Condition: (count(empsalary.empno) OVER w1 <= 3)
-> Sort
Sort Key: empsalary.depname, empsalary.salary DESC
-> Seq Scan on empsalary
(5 rows)
(6 rows)
-- and again, check the results are what we expect.
SELECT * FROM
@ -4130,11 +4151,12 @@ SELECT * FROM
FROM empsalary) emp
WHERE c = 1;
QUERY PLAN
--------------------------------------------------------
-------------------------------------------------------
WindowAgg
Run Condition: (count(empsalary.empno) OVER (?) = 1)
Window: w1 AS ()
Run Condition: (count(empsalary.empno) OVER w1 = 1)
-> Seq Scan on empsalary
(3 rows)
(4 rows)
-- Try another case with a WindowFunc with a byref return type
SELECT * FROM
@ -4158,22 +4180,25 @@ SELECT * FROM
FROM empsalary
) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2;
QUERY PLAN
-----------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------
Subquery Scan on e
-> WindowAgg
Filter: (((row_number() OVER (?)) <= 1) AND ((ntile(2) OVER (?)) < 2))
Run Condition: (count(empsalary.salary) OVER (?) <= 3)
Window: w3 AS (PARTITION BY (((empsalary.depname)::text || ''::text)))
Run Condition: (count(empsalary.salary) OVER w3 <= 3)
Filter: (((row_number() OVER w2) <= 1) AND ((ntile(2) OVER w2) < 2))
-> Sort
Sort Key: (((empsalary.depname)::text || ''::text))
-> WindowAgg
Run Condition: ((row_number() OVER (?) <= 1) AND (ntile(2) OVER (?) < 2))
Window: w2 AS (PARTITION BY empsalary.depname)
Run Condition: ((row_number() OVER w2 <= 1) AND (ntile(2) OVER w2 < 2))
-> Sort
Sort Key: empsalary.depname
-> WindowAgg
Window: w1 AS (PARTITION BY ((''::text || (empsalary.depname)::text)))
-> Sort
Sort Key: ((''::text || (empsalary.depname)::text))
-> Seq Scan on empsalary
(14 rows)
(17 rows)
-- Ensure we correctly filter out all of the run conditions from each window
SELECT * FROM
@ -4200,11 +4225,12 @@ SELECT 1 FROM
WHERE e1.empno = e2.empno) s
WHERE s.c = 1;
QUERY PLAN
---------------------------------------------------------
--------------------------------------------------------------------------
Subquery Scan on s
Filter: (s.c = 1)
-> WindowAgg
Run Condition: (ntile(e2.salary) OVER (?) <= 1)
Window: w1 AS (PARTITION BY e1.depname ROWS UNBOUNDED PRECEDING)
Run Condition: (ntile(e2.salary) OVER w1 <= 1)
-> Sort
Sort Key: e1.depname
-> Merge Join
@ -4215,7 +4241,7 @@ WHERE s.c = 1;
-> Sort
Sort Key: e2.empno
-> Seq Scan on empsalary e2
(14 rows)
(15 rows)
-- Ensure the run condition optimization is used in cases where the WindowFunc
-- has a Var from another query level
@ -4225,15 +4251,16 @@ SELECT 1 FROM
FROM (SELECT (SELECT 1) AS x) AS s1) s
WHERE s.c = 1;
QUERY PLAN
-----------------------------------------------------------------
----------------------------------------------------------------
Subquery Scan on s
Filter: (s.c = 1)
-> WindowAgg
Run Condition: (ntile((InitPlan 1).col1) OVER (?) <= 1)
Window: w1 AS (ROWS UNBOUNDED PRECEDING)
Run Condition: (ntile((InitPlan 1).col1) OVER w1 <= 1)
InitPlan 1
-> Result
-> Result
(7 rows)
(8 rows)
-- Tests to ensure we don't push down the run condition when it's not valid to
-- do so.
@ -4247,14 +4274,15 @@ SELECT * FROM
FROM empsalary) emp
WHERE c <= 3;
QUERY PLAN
-----------------------------------------------
----------------------------------------------------------------------------------------------------
Subquery Scan on emp
Filter: (emp.c <= 3)
-> WindowAgg
Window: w1 AS (ORDER BY empsalary.salary ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
-> Sort
Sort Key: empsalary.salary DESC
-> Seq Scan on empsalary
(6 rows)
(7 rows)
-- Ensure we don't push down when the window function's monotonic properties
-- don't match that of the clauses.
@ -4266,14 +4294,15 @@ SELECT * FROM
FROM empsalary) emp
WHERE 3 <= c;
QUERY PLAN
------------------------------------------
---------------------------------------------------
Subquery Scan on emp
Filter: (3 <= emp.c)
-> WindowAgg
Window: w1 AS (ORDER BY empsalary.salary)
-> Sort
Sort Key: empsalary.salary
-> Seq Scan on empsalary
(6 rows)
(7 rows)
-- Ensure we don't use a run condition when there's a volatile function in the
-- WindowFunc
@ -4285,14 +4314,15 @@ SELECT * FROM
FROM empsalary) emp
WHERE c = 1;
QUERY PLAN
----------------------------------------------
--------------------------------------------------
Subquery Scan on emp
Filter: (emp.c = 1)
-> WindowAgg
Window: w1 AS (ORDER BY empsalary.empno)
-> Sort
Sort Key: empsalary.empno DESC
-> Seq Scan on empsalary
(6 rows)
(7 rows)
-- Ensure we don't use a run condition when the WindowFunc contains subplans
EXPLAIN (COSTS OFF)
@ -4303,16 +4333,17 @@ SELECT * FROM
FROM empsalary) emp
WHERE c = 1;
QUERY PLAN
----------------------------------------------
--------------------------------------------------
Subquery Scan on emp
Filter: (emp.c = 1)
-> WindowAgg
Window: w1 AS (ORDER BY empsalary.empno)
InitPlan 1
-> Result
-> Sort
Sort Key: empsalary.empno DESC
-> Seq Scan on empsalary
(8 rows)
(9 rows)
-- Test Sort node collapsing
EXPLAIN (COSTS OFF)
@ -4323,15 +4354,17 @@ SELECT * FROM
FROM empsalary) emp
WHERE depname = 'sales';
QUERY PLAN
----------------------------------------------------------------------
-------------------------------------------------------------------------------------------
Subquery Scan on emp
-> WindowAgg
Window: w2 AS (ORDER BY empsalary.empno)
-> WindowAgg
Window: w1 AS (PARTITION BY empsalary.empno ORDER BY empsalary.enroll_date)
-> Sort
Sort Key: empsalary.empno, empsalary.enroll_date
-> Seq Scan on empsalary
Filter: ((depname)::text = 'sales'::text)
(7 rows)
(9 rows)
-- Ensure that the evaluation order of the WindowAggs results in the WindowAgg
-- with the same sort order that's required by the ORDER BY is evaluated last.
@ -4344,16 +4377,18 @@ SELECT empno,
FROM empsalary
ORDER BY depname, empno;
QUERY PLAN
----------------------------------------------------
-------------------------------------------------------------------------
WindowAgg
Window: w2 AS (PARTITION BY depname ORDER BY empno)
-> Incremental Sort
Sort Key: depname, empno
Presorted Key: depname
-> WindowAgg
Window: w1 AS (PARTITION BY depname ORDER BY enroll_date)
-> Sort
Sort Key: depname, enroll_date
-> Seq Scan on empsalary
(8 rows)
(10 rows)
-- As above, but with an adjusted ORDER BY to ensure the above plan didn't
-- perform only 2 sorts by accident.
@ -4366,16 +4401,18 @@ SELECT empno,
FROM empsalary
ORDER BY depname, enroll_date;
QUERY PLAN
-----------------------------------------------
-------------------------------------------------------------------
WindowAgg
Window: w2 AS (PARTITION BY depname ORDER BY enroll_date)
-> Incremental Sort
Sort Key: depname, enroll_date
Presorted Key: depname
-> WindowAgg
Window: w1 AS (PARTITION BY depname ORDER BY empno)
-> Sort
Sort Key: depname, empno
-> Seq Scan on empsalary
(8 rows)
(10 rows)
SET enable_hashagg TO off;
-- Ensure we don't get a sort for both DISTINCT and ORDER BY. We expect the
@ -4390,20 +4427,22 @@ SELECT DISTINCT
FROM empsalary
ORDER BY depname, enroll_date;
QUERY PLAN
-----------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
Unique
-> Incremental Sort
Sort Key: depname, enroll_date, empno, (sum(salary) OVER (?)), (min(salary) OVER (?) )
Sort Key: depname, enroll_date, empno, (sum(salary) OVER w1), (min(salary) OVER w2 )
Presorted Key: depname, enroll_date
-> WindowAgg
Window: w2 AS (PARTITION BY depname ORDER BY enroll_date)
-> Incremental Sort
Sort Key: depname, enroll_date
Presorted Key: depname
-> WindowAgg
Window: w1 AS (PARTITION BY depname ORDER BY empno)
-> Sort
Sort Key: depname, empno
-> Seq Scan on empsalary
(12 rows)
(14 rows)
-- As above but adjust the ORDER BY clause to help ensure the plan with the
-- minimum amount of sorting wasn't a fluke.
@ -4417,20 +4456,22 @@ SELECT DISTINCT
FROM empsalary
ORDER BY depname, empno;
QUERY PLAN
-----------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
Unique
-> Incremental Sort
Sort Key: depname, empno, enroll_date, (sum(salary) OVER (?)), (min(salary) OVER (?) )
Sort Key: depname, empno, enroll_date, (sum(salary) OVER w2), (min(salary) OVER w1 )
Presorted Key: depname, empno
-> WindowAgg
Window: w2 AS (PARTITION BY depname ORDER BY empno)
-> Incremental Sort
Sort Key: depname, empno
Presorted Key: depname
-> WindowAgg
Window: w1 AS (PARTITION BY depname ORDER BY enroll_date)
-> Sort
Sort Key: depname, enroll_date
-> Seq Scan on empsalary
(12 rows)
(14 rows)
RESET enable_hashagg;
-- Test Sort node reordering
@ -4440,13 +4481,15 @@ SELECT
lag(1) OVER (PARTITION BY depname ORDER BY salary,enroll_date,empno)
FROM empsalary;
QUERY PLAN
-------------------------------------------------------------
----------------------------------------------------------------------------------
WindowAgg
Window: w2 AS (PARTITION BY depname ORDER BY salary, enroll_date)
-> WindowAgg
Window: w1 AS (PARTITION BY depname ORDER BY salary, enroll_date, empno)
-> Sort
Sort Key: depname, salary, enroll_date, empno
-> Seq Scan on empsalary
(5 rows)
(7 rows)
-- Test incremental sorting
EXPLAIN (COSTS OFF)
@ -4460,18 +4503,20 @@ SELECT * FROM
FROM empsalary) emp
WHERE first_emp = 1 OR last_emp = 1;
QUERY PLAN
-----------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
Subquery Scan on emp
Filter: ((emp.first_emp = 1) OR (emp.last_emp = 1))
-> WindowAgg
Window: w2 AS (PARTITION BY empsalary.depname ORDER BY empsalary.enroll_date ROWS UNBOUNDED PRECEDING)
-> Incremental Sort
Sort Key: empsalary.depname, empsalary.enroll_date
Presorted Key: empsalary.depname
-> WindowAgg
Window: w1 AS (PARTITION BY empsalary.depname ORDER BY empsalary.enroll_date ROWS UNBOUNDED PRECEDING)
-> Sort
Sort Key: empsalary.depname, empsalary.enroll_date DESC
-> Seq Scan on empsalary
(10 rows)
(12 rows)
SELECT * FROM
(SELECT depname,
@ -5299,11 +5344,12 @@ LIMIT 1;
--------------------------------------------------------------------------
Limit
-> WindowAgg
Window: w1 AS (ORDER BY t1.unique1)
-> Nested Loop
-> Index Only Scan using tenk1_unique1 on tenk1 t1
-> Index Only Scan using tenk1_thous_tenthous on tenk1 t2
Index Cond: (tenthous = t1.unique1)
(6 rows)
(7 rows)
-- Ensure we get a cheap total plan. Lack of ORDER BY in the WindowClause
-- means that all rows must be read from the join, so a cheap startup plan
@ -5317,13 +5363,14 @@ LIMIT 1;
-------------------------------------------------------------------
Limit
-> WindowAgg
Window: w1 AS ()
-> Hash Join
Hash Cond: (t1.unique1 = t2.tenthous)
-> Index Only Scan using tenk1_unique1 on tenk1 t1
-> Hash
-> Seq Scan on tenk1 t2
Filter: (two = 1)
(8 rows)
(9 rows)
-- Ensure we get a cheap total plan. This time use UNBOUNDED FOLLOWING, which
-- needs to read all join rows to output the first WindowAgg row.
@ -5332,16 +5379,17 @@ SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND U
FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous
LIMIT 1;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
Limit
-> WindowAgg
Window: w1 AS (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
-> Merge Join
Merge Cond: (t1.unique1 = t2.tenthous)
-> Index Only Scan using tenk1_unique1 on tenk1 t1
-> Sort
Sort Key: t2.tenthous
-> Index Only Scan using tenk1_thous_tenthous on tenk1 t2
(8 rows)
(9 rows)
-- Ensure we get a cheap total plan. This time use 10000 FOLLOWING so we need
-- to read all join rows.
@ -5350,16 +5398,17 @@ SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND 1
FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous
LIMIT 1;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
Limit
-> WindowAgg
Window: w1 AS (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND '10000'::bigint FOLLOWING)
-> Merge Join
Merge Cond: (t1.unique1 = t2.tenthous)
-> Index Only Scan using tenk1_unique1 on tenk1 t1
-> Sort
Sort Key: t2.tenthous
-> Index Only Scan using tenk1_thous_tenthous on tenk1 t2
(8 rows)
(9 rows)
-- Tests for problems with failure to walk or mutate expressions
-- within window frame clauses.
@ -5385,13 +5434,14 @@ AS $$
$$ LANGUAGE SQL STABLE;
EXPLAIN (costs off) SELECT * FROM pg_temp.f(2);
QUERY PLAN
------------------------------------------------------
----------------------------------------------------------------------------------------
Subquery Scan on f
-> WindowAgg
Window: w AS (ORDER BY s.s ROWS BETWEEN CURRENT ROW AND '2'::bigint FOLLOWING)
-> Sort
Sort Key: s.s
-> Function Scan on generate_series s
(5 rows)
(6 rows)
SELECT * FROM pg_temp.f(2);
f