1--
2-- MULTI_COMPLEX_EXPRESSIONS
3--
4
5-- Check that we can correctly handle complex expressions and aggregates.
6
7
8SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem;
9
10SELECT sum(l_quantity) / (10 * avg(l_quantity)) FROM lineitem;
11
12SELECT (sum(l_quantity) / (10 * avg(l_quantity))) + 11 FROM lineitem;
13
14SELECT avg(l_quantity) as average FROM lineitem;
15
16SELECT 100 * avg(l_quantity) as average_times_hundred FROM lineitem;
17
18SELECT 100 * avg(l_quantity) / 10 as average_times_ten FROM lineitem;
19
20SELECT l_quantity, 10 * count(*) count_quantity FROM lineitem
21	GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
22
23-- Check that we can handle complex select clause expressions.
24
25SELECT count(*) FROM lineitem
26	WHERE octet_length(l_comment || l_comment) > 40;
27
28SELECT count(*) FROM lineitem
29	WHERE octet_length(concat(l_comment, l_comment)) > 40;
30
31SELECT count(*) FROM lineitem
32	WHERE octet_length(l_comment) + octet_length('randomtext'::text) > 40;
33
34SELECT count(*) FROM lineitem
35	WHERE octet_length(l_comment) + 10 > 40;
36
37SELECT count(*) FROM lineitem
38	WHERE (l_receiptdate::timestamp - l_shipdate::timestamp) > interval '5 days';
39
40-- can push down queries where no columns present on the WHERE clause
41SELECT count(*) FROM lineitem WHERE random() = -0.1;
42
43-- boolean tests can be pushed down
44SELECT count(*) FROM lineitem
45	WHERE (l_partkey > 10000) is true;
46
47-- scalar array operator expressions can be pushed down
48SELECT count(*) FROM lineitem
49	WHERE l_partkey = ANY(ARRAY[19353, 19354, 19355]);
50
51-- some more scalar array operator expressions
52SELECT count(*) FROM lineitem
53	WHERE l_partkey = ALL(ARRAY[19353]);
54
55-- operator expressions involving arrays
56SELECT count(*) FROM lineitem
57	WHERE ARRAY[19353, 19354, 19355] @> ARRAY[l_partkey];
58
59-- coerced via io expressions can be pushed down
60SELECT count(*) FROM lineitem
61	WHERE (l_quantity/100)::int::bool::text::bool;
62
63-- case expressions can be pushed down
64SELECT count(*) FROM lineitem
65	WHERE (CASE WHEN l_orderkey > 4000 THEN l_partkey / 100 > 1 ELSE false END);
66
67-- coalesce expressions can be pushed down
68SELECT count(*) FROM lineitem
69	WHERE COALESCE((l_partkey/50000)::bool, false);
70
71-- nullif expressions can be pushed down
72SELECT count(*) FROM lineitem
73	WHERE NULLIF((l_partkey/50000)::bool, false);
74
75-- null test expressions can be pushed down
76SELECT count(*) FROM orders
77	WHERE o_comment IS NOT null;
78
79-- functions can be pushed down
80SELECT count(*) FROM lineitem
81	WHERE isfinite(l_shipdate);
82
83-- constant expressions can be pushed down
84SELECT count(*) FROM lineitem
85	WHERE 0 != 0;
86
87-- distinct expressions can be pushed down
88SELECT count(*) FROM lineitem
89	WHERE l_partkey IS DISTINCT FROM 50040;
90
91-- row compare expression can be pushed down
92SELECT count(*) FROM lineitem
93	WHERE row(l_partkey, 2, 3) > row(2000, 2, 3);
94
95-- combination of different expressions can be pushed down
96SELECT count(*) FROM lineitem
97	WHERE
98		  (l_quantity/100)::int::bool::text::bool AND
99		  CASE WHEN l_orderkey > 4000 THEN l_partkey / 100 > 1 ELSE false END AND
100		  COALESCE((l_partkey/50000)::bool, false) AND
101		  NULLIF((l_partkey/50000)::bool, false) AND
102		  isfinite(l_shipdate) AND
103		  l_partkey IS DISTINCT FROM 50040 AND
104		  row(l_partkey, 2, 3) > row(2000, 2, 3);
105
106-- constant expression in the WHERE clause with a column in the target list
107SELECT l_linenumber FROM lineitem
108	WHERE
109		1!=0
110	ORDER BY
111		l_linenumber
112	LIMIT 1;
113
114-- constant expression in the WHERE clause with expressions and a column the target list
115SELECT count(*) * l_discount as total_discount, count(*), sum(l_tax), l_discount FROM lineitem
116	WHERE
117		1!=0
118	GROUP BY
119		l_discount
120	ORDER BY
121		total_discount DESC, sum(l_tax) DESC;
122
123-- distinct expressions in the WHERE clause with a column in the target list
124SELECT l_linenumber FROM lineitem
125	WHERE
126		l_linenumber IS DISTINCT FROM 1 AND
127		l_orderkey IS DISTINCT FROM 8997
128	ORDER BY
129		l_linenumber
130	LIMIT 1;
131
132-- distinct expressions in the WHERE clause with expressions and a column the target list
133SELECT max(l_linenumber), min(l_discount), l_receiptdate FROM lineitem
134	WHERE
135		l_linenumber IS DISTINCT FROM 1 AND
136		l_orderkey IS DISTINCT FROM 8997
137	GROUP BY
138		l_receiptdate
139	ORDER BY
140		l_receiptdate
141	LIMIT 1;
142
143-- Check that we can handle implicit and explicit join clause definitions.
144
145SELECT count(*) FROM lineitem, orders
146	WHERE l_orderkey = o_orderkey AND l_quantity < 5;
147
148SELECT count(*) FROM lineitem
149	JOIN orders ON l_orderkey = o_orderkey AND l_quantity < 5;
150
151SELECT count(*) FROM lineitem JOIN orders ON l_orderkey = o_orderkey
152	WHERE l_quantity < 5;
153
154-- Check that we make sure local joins are between columns only.
155
156SELECT count(*) FROM lineitem, orders WHERE l_orderkey + 1 = o_orderkey;
157
158-- Check that we can issue limit/offset queries
159
160-- the subquery is recursively planned since it contains OFFSET, which is not pushdownable
161SELECT * FROM (SELECT o_custkey FROM orders GROUP BY o_custkey ORDER BY o_custkey OFFSET 20) sq ORDER BY 1 LIMIT 5;
162
163-- the subquery is recursively planned since it contains OFFSET, which is not pushdownable
164SELECT * FROM (SELECT o_orderkey FROM orders ORDER BY o_orderkey OFFSET 20) sq ORDER BY 1 LIMIT 5;
165
166-- Simple LIMIT/OFFSET with ORDER BY
167SELECT o_orderkey FROM orders ORDER BY o_orderkey LIMIT 10 OFFSET 20;
168
169-- LIMIT/OFFSET with a subquery
170
171SELECT
172	customer_keys.o_custkey,
173	SUM(order_count) AS total_order_count
174FROM
175	(SELECT o_custkey, o_orderstatus, COUNT(*) AS order_count
176	 FROM orders GROUP BY o_custkey, o_orderstatus ) customer_keys
177GROUP BY
178	customer_keys.o_custkey
179ORDER BY
180	customer_keys.o_custkey DESC
181LIMIT 10 OFFSET 20;
182
183SELECT
184	customer_keys.o_custkey,
185	SUM(order_count) AS total_order_count
186FROM
187	(SELECT o_custkey, o_orderstatus, COUNT(*) over (partition by o_orderstatus) AS order_count
188	 FROM orders GROUP BY o_custkey, o_orderstatus ) customer_keys
189GROUP BY
190	customer_keys.o_custkey
191ORDER BY
192	customer_keys.o_custkey DESC
193LIMIT 10 OFFSET 20;
194
195SELECT
196	customer_keys.o_custkey,
197	SUM(order_count1 + order_count) AS total_order_count
198FROM
199	(SELECT o_custkey, o_orderstatus, count(*) order_count1, COUNT(*) over (partition by o_orderstatus) AS order_count
200	 FROM orders GROUP BY o_custkey, o_orderstatus ) customer_keys
201GROUP BY
202	customer_keys.o_custkey
203ORDER BY
204	customer_keys.o_custkey DESC
205LIMIT 10 OFFSET 20;
206
207SET client_min_messages TO DEBUG1;
208
209-- Ensure that we push down LIMIT and OFFSET properly
210-- No Group-By -> Push Down
211CREATE TEMP TABLE temp_limit_test_1 AS
212SELECT o_custkey FROM orders LIMIT 10 OFFSET 15;
213
214-- GROUP BY without ORDER BY -> No push-down
215CREATE TEMP TABLE temp_limit_test_2 AS
216SELECT o_custkey FROM orders GROUP BY o_custkey LIMIT 10 OFFSET 15;
217
218-- GROUP BY and ORDER BY non-aggregate -> push-down
219CREATE TEMP TABLE temp_limit_test_3 AS
220SELECT o_custkey FROM orders GROUP BY o_custkey ORDER BY o_custkey LIMIT 10 OFFSET 15;
221
222-- GROUP BY and ORDER BY aggregate -> No push-down
223CREATE TEMP TABLE temp_limit_test_4 AS
224SELECT o_custkey, COUNT(*) AS ccnt FROM orders GROUP BY o_custkey ORDER BY ccnt DESC LIMIT 10 OFFSET 15;
225
226-- OFFSET without LIMIT
227SELECT o_custkey FROM orders ORDER BY o_custkey OFFSET 2980;
228
229-- LIMIT/OFFSET with Joins
230SELECT
231	li.l_partkey,
232	o.o_custkey,
233	li.l_quantity
234FROM
235	lineitem li JOIN orders o ON li.l_orderkey = o.o_orderkey
236WHERE
237	li.l_quantity > 25
238ORDER BY 1, 2, 3
239LIMIT 10 OFFSET 20;
240
241RESET client_min_messages;
242
243-- FILTERs
244SELECT
245	l_orderkey,
246	sum(l_extendedprice),
247	sum(l_extendedprice) FILTER (WHERE l_shipmode = 'AIR'),
248	count(*),
249	count(*) FILTER (WHERE l_shipmode = 'AIR'),
250	max(l_extendedprice),
251	max(l_extendedprice) FILTER (WHERE l_quantity < 30)
252	FROM lineitem
253	GROUP BY l_orderkey
254	ORDER BY 2 DESC, 1 DESC
255	LIMIT 10;
256
257SELECT
258	l_orderkey,
259	sum(l_extendedprice),
260	sum(l_extendedprice) FILTER (WHERE l_shipmode = 'AIR'),
261	count(*),
262	count(*) FILTER (WHERE l_shipmode = 'AIR'),
263	max(l_extendedprice),
264	max(l_extendedprice) FILTER (WHERE l_quantity < 30)
265	FROM lineitem
266	GROUP BY l_orderkey
267	HAVING count(*) FILTER (WHERE l_shipmode = 'AIR') > 1
268	ORDER BY 2 DESC, 1 DESC
269	LIMIT 10;
270
271