@@ -190,8 +190,207 @@ SELECT COUNT(*) FROM ONLY test.num_range_rel;
190190 0
191191(1 row)
192192
193- SELECT * FROM ONLY test.range_rel UNION SELECT * FROM test.range_rel;
194- ERROR: It is prohibited to query partitioned tables both with and without ONLY modifier
193+ /* test special case: ONLY statement with not-ONLY for partitioned table */
194+ CREATE TABLE test.from_only_test(val INT NOT NULL);
195+ INSERT INTO test.from_only_test SELECT generate_series(1, 20);
196+ SELECT pathman.create_range_partitions('test.from_only_test', 'val', 1, 2);
197+ NOTICE: sequence "from_only_test_seq" does not exist, skipping
198+ create_range_partitions
199+ -------------------------
200+ 10
201+ (1 row)
202+
203+ /* should be OK */
204+ EXPLAIN (COSTS OFF)
205+ SELECT * FROM ONLY test.from_only_test
206+ UNION SELECT * FROM test.from_only_test;
207+ QUERY PLAN
208+ -------------------------------------------------
209+ HashAggregate
210+ Group Key: from_only_test.val
211+ -> Append
212+ -> Seq Scan on from_only_test
213+ -> Append
214+ -> Seq Scan on from_only_test_1
215+ -> Seq Scan on from_only_test_2
216+ -> Seq Scan on from_only_test_3
217+ -> Seq Scan on from_only_test_4
218+ -> Seq Scan on from_only_test_5
219+ -> Seq Scan on from_only_test_6
220+ -> Seq Scan on from_only_test_7
221+ -> Seq Scan on from_only_test_8
222+ -> Seq Scan on from_only_test_9
223+ -> Seq Scan on from_only_test_10
224+ (15 rows)
225+
226+ /* should be OK */
227+ EXPLAIN (COSTS OFF)
228+ SELECT * FROM test.from_only_test
229+ UNION SELECT * FROM ONLY test.from_only_test;
230+ QUERY PLAN
231+ -------------------------------------------------
232+ HashAggregate
233+ Group Key: from_only_test_1.val
234+ -> Append
235+ -> Append
236+ -> Seq Scan on from_only_test_1
237+ -> Seq Scan on from_only_test_2
238+ -> Seq Scan on from_only_test_3
239+ -> Seq Scan on from_only_test_4
240+ -> Seq Scan on from_only_test_5
241+ -> Seq Scan on from_only_test_6
242+ -> Seq Scan on from_only_test_7
243+ -> Seq Scan on from_only_test_8
244+ -> Seq Scan on from_only_test_9
245+ -> Seq Scan on from_only_test_10
246+ -> Seq Scan on from_only_test
247+ (15 rows)
248+
249+ /* should be OK */
250+ EXPLAIN (COSTS OFF)
251+ SELECT * FROM test.from_only_test
252+ UNION SELECT * FROM test.from_only_test
253+ UNION SELECT * FROM ONLY test.from_only_test;
254+ QUERY PLAN
255+ ---------------------------------------------------------------------
256+ HashAggregate
257+ Group Key: from_only_test_1.val
258+ -> Append
259+ -> Append
260+ -> Seq Scan on from_only_test_1
261+ -> Seq Scan on from_only_test_2
262+ -> Seq Scan on from_only_test_3
263+ -> Seq Scan on from_only_test_4
264+ -> Seq Scan on from_only_test_5
265+ -> Seq Scan on from_only_test_6
266+ -> Seq Scan on from_only_test_7
267+ -> Seq Scan on from_only_test_8
268+ -> Seq Scan on from_only_test_9
269+ -> Seq Scan on from_only_test_10
270+ -> Append
271+ -> Seq Scan on from_only_test_1 from_only_test_1_1
272+ -> Seq Scan on from_only_test_2 from_only_test_2_1
273+ -> Seq Scan on from_only_test_3 from_only_test_3_1
274+ -> Seq Scan on from_only_test_4 from_only_test_4_1
275+ -> Seq Scan on from_only_test_5 from_only_test_5_1
276+ -> Seq Scan on from_only_test_6 from_only_test_6_1
277+ -> Seq Scan on from_only_test_7 from_only_test_7_1
278+ -> Seq Scan on from_only_test_8 from_only_test_8_1
279+ -> Seq Scan on from_only_test_9 from_only_test_9_1
280+ -> Seq Scan on from_only_test_10 from_only_test_10_1
281+ -> Seq Scan on from_only_test
282+ (26 rows)
283+
284+ /* should be OK */
285+ EXPLAIN (COSTS OFF)
286+ SELECT * FROM ONLY test.from_only_test
287+ UNION SELECT * FROM test.from_only_test
288+ UNION SELECT * FROM test.from_only_test;
289+ QUERY PLAN
290+ ---------------------------------------------------------------------
291+ HashAggregate
292+ Group Key: from_only_test.val
293+ -> Append
294+ -> Seq Scan on from_only_test
295+ -> Append
296+ -> Seq Scan on from_only_test_1
297+ -> Seq Scan on from_only_test_2
298+ -> Seq Scan on from_only_test_3
299+ -> Seq Scan on from_only_test_4
300+ -> Seq Scan on from_only_test_5
301+ -> Seq Scan on from_only_test_6
302+ -> Seq Scan on from_only_test_7
303+ -> Seq Scan on from_only_test_8
304+ -> Seq Scan on from_only_test_9
305+ -> Seq Scan on from_only_test_10
306+ -> Append
307+ -> Seq Scan on from_only_test_1 from_only_test_1_1
308+ -> Seq Scan on from_only_test_2 from_only_test_2_1
309+ -> Seq Scan on from_only_test_3 from_only_test_3_1
310+ -> Seq Scan on from_only_test_4 from_only_test_4_1
311+ -> Seq Scan on from_only_test_5 from_only_test_5_1
312+ -> Seq Scan on from_only_test_6 from_only_test_6_1
313+ -> Seq Scan on from_only_test_7 from_only_test_7_1
314+ -> Seq Scan on from_only_test_8 from_only_test_8_1
315+ -> Seq Scan on from_only_test_9 from_only_test_9_1
316+ -> Seq Scan on from_only_test_10 from_only_test_10_1
317+ (26 rows)
318+
319+ /* not ok, ONLY|non-ONLY in one query */
320+ EXPLAIN (COSTS OFF)
321+ SELECT * FROM test.from_only_test a JOIN ONLY test.from_only_test b USING(val);
322+ ERROR: It is prohibited to apply ONLY modifier to partitioned tables which have already been mentioned without ONLY
323+ EXPLAIN (COSTS OFF)
324+ WITH q1 AS (SELECT * FROM test.from_only_test),
325+ q2 AS (SELECT * FROM ONLY test.from_only_test)
326+ SELECT * FROM q1 JOIN q2 USING(val);
327+ QUERY PLAN
328+ ---------------------------------------------
329+ Hash Join
330+ Hash Cond: (q1.val = q2.val)
331+ CTE q1
332+ -> Append
333+ -> Seq Scan on from_only_test_1
334+ -> Seq Scan on from_only_test_2
335+ -> Seq Scan on from_only_test_3
336+ -> Seq Scan on from_only_test_4
337+ -> Seq Scan on from_only_test_5
338+ -> Seq Scan on from_only_test_6
339+ -> Seq Scan on from_only_test_7
340+ -> Seq Scan on from_only_test_8
341+ -> Seq Scan on from_only_test_9
342+ -> Seq Scan on from_only_test_10
343+ CTE q2
344+ -> Seq Scan on from_only_test
345+ -> CTE Scan on q1
346+ -> Hash
347+ -> CTE Scan on q2
348+ (19 rows)
349+
350+ EXPLAIN (COSTS OFF)
351+ WITH q1 AS (SELECT * FROM ONLY test.from_only_test)
352+ SELECT * FROM test.from_only_test JOIN q1 USING(val);
353+ QUERY PLAN
354+ ----------------------------------------------
355+ Hash Join
356+ Hash Cond: (from_only_test_1.val = q1.val)
357+ CTE q1
358+ -> Seq Scan on from_only_test
359+ -> Append
360+ -> Seq Scan on from_only_test_1
361+ -> Seq Scan on from_only_test_2
362+ -> Seq Scan on from_only_test_3
363+ -> Seq Scan on from_only_test_4
364+ -> Seq Scan on from_only_test_5
365+ -> Seq Scan on from_only_test_6
366+ -> Seq Scan on from_only_test_7
367+ -> Seq Scan on from_only_test_8
368+ -> Seq Scan on from_only_test_9
369+ -> Seq Scan on from_only_test_10
370+ -> Hash
371+ -> CTE Scan on q1
372+ (17 rows)
373+
374+ EXPLAIN (COSTS OFF)
375+ SELECT * FROM test.range_rel WHERE id = (SELECT id FROM ONLY test.range_rel LIMIT 1);
376+ QUERY PLAN
377+ --------------------------------------------------------
378+ Append
379+ InitPlan 1 (returns $0)
380+ -> Limit
381+ -> Seq Scan on range_rel
382+ -> Index Scan using range_rel_1_pkey on range_rel_1
383+ Index Cond: (id = $0)
384+ -> Index Scan using range_rel_2_pkey on range_rel_2
385+ Index Cond: (id = $0)
386+ -> Index Scan using range_rel_3_pkey on range_rel_3
387+ Index Cond: (id = $0)
388+ -> Index Scan using range_rel_4_pkey on range_rel_4
389+ Index Cond: (id = $0)
390+ (12 rows)
391+
392+ DROP TABLE test.from_only_test CASCADE;
393+ NOTICE: drop cascades to 10 other objects
195394SET pg_pathman.enable_runtimeappend = OFF;
196395SET pg_pathman.enable_runtimemergeappend = OFF;
197396VACUUM;
@@ -308,6 +507,48 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE (id >= 500 AND id < 1
308507 -> Seq Scan on num_range_rel_4
309508(8 rows)
310509
510+ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE id IN (2500);
511+ QUERY PLAN
512+ -----------------------------------
513+ Append
514+ -> Seq Scan on num_range_rel_3
515+ Filter: (id = 2500)
516+ (3 rows)
517+
518+ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE id IN (500, 1500);
519+ QUERY PLAN
520+ ------------------------------------------------------
521+ Append
522+ -> Seq Scan on num_range_rel_1
523+ Filter: (id = ANY ('{500,1500}'::integer[]))
524+ -> Seq Scan on num_range_rel_2
525+ Filter: (id = ANY ('{500,1500}'::integer[]))
526+ (5 rows)
527+
528+ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE id IN (-500, 500, 1500);
529+ QUERY PLAN
530+ -----------------------------------------------------------
531+ Append
532+ -> Seq Scan on num_range_rel_1
533+ Filter: (id = ANY ('{-500,500,1500}'::integer[]))
534+ -> Seq Scan on num_range_rel_2
535+ Filter: (id = ANY ('{-500,500,1500}'::integer[]))
536+ (5 rows)
537+
538+ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE id IN (-1, -1, -1);
539+ QUERY PLAN
540+ --------------------------
541+ Result
542+ One-Time Filter: false
543+ (2 rows)
544+
545+ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE id IN (-1, -1, -1, NULL);
546+ QUERY PLAN
547+ --------------------------
548+ Result
549+ One-Time Filter: false
550+ (2 rows)
551+
311552EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt > '2015-02-15';
312553 QUERY PLAN
313554--------------------------------------------------------------------------------
@@ -378,6 +619,59 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel WHERE value = 2 OR value = 1;
378619 Filter: (value = 1)
379620(5 rows)
380621
622+ EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel WHERE value IN (2);
623+ QUERY PLAN
624+ ------------------------------
625+ Append
626+ -> Seq Scan on hash_rel_1
627+ Filter: (value = 2)
628+ (3 rows)
629+
630+ EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel WHERE value IN (2, 1);
631+ QUERY PLAN
632+ ----------------------------------------------------
633+ Append
634+ -> Seq Scan on hash_rel_1
635+ Filter: (value = ANY ('{2,1}'::integer[]))
636+ -> Seq Scan on hash_rel_2
637+ Filter: (value = ANY ('{2,1}'::integer[]))
638+ (5 rows)
639+
640+ EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel WHERE value IN (1, 2);
641+ QUERY PLAN
642+ ----------------------------------------------------
643+ Append
644+ -> Seq Scan on hash_rel_1
645+ Filter: (value = ANY ('{1,2}'::integer[]))
646+ -> Seq Scan on hash_rel_2
647+ Filter: (value = ANY ('{1,2}'::integer[]))
648+ (5 rows)
649+
650+ EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel WHERE value IN (1, 2, -1);
651+ QUERY PLAN
652+ -------------------------------------------------------
653+ Append
654+ -> Seq Scan on hash_rel_1
655+ Filter: (value = ANY ('{1,2,-1}'::integer[]))
656+ -> Seq Scan on hash_rel_2
657+ Filter: (value = ANY ('{1,2,-1}'::integer[]))
658+ (5 rows)
659+
660+ EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel WHERE value IN (0, 0, 0);
661+ QUERY PLAN
662+ ------------------------------------------------------
663+ Append
664+ -> Seq Scan on hash_rel_1
665+ Filter: (value = ANY ('{0,0,0}'::integer[]))
666+ (3 rows)
667+
668+ EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel WHERE value IN (NULL::int, NULL, NULL);
669+ QUERY PLAN
670+ --------------------------
671+ Result
672+ One-Time Filter: false
673+ (2 rows)
674+
381675EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE id > 2500;
382676 QUERY PLAN
383677----------------------------------------------------------------
@@ -1543,6 +1837,6 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.index_on_childs WHERE c1 > 100 AND c1 < 2
15431837(12 rows)
15441838
15451839DROP SCHEMA test CASCADE;
1546- NOTICE: drop cascades to45 other objects
1840+ NOTICE: drop cascades to46 other objects
15471841DROP EXTENSION pg_pathman CASCADE;
15481842DROP SCHEMA pathman CASCADE;