@@ -406,6 +406,84 @@ def test_foreign_table(self):
406
406
# Testing drop partitions (including foreign partitions)
407
407
master .safe_psql ('postgres' , 'select drop_partitions(\' abc\' )' )
408
408
409
+ def test_parallel_nodes (self ):
410
+ """Test parallel queries under partitions"""
411
+
412
+ # Init and start postgres instance with preload pg_pathman module
413
+ node = get_new_node ('test' )
414
+ node .init ()
415
+ node .append_conf (
416
+ 'postgresql.conf' ,
417
+ 'shared_preload_libraries=\' pg_pathman, postgres_fdw\' \n ' )
418
+ node .start ()
419
+
420
+ # Check version of postgres server
421
+ # If version < 9.6 skip all tests for parallel queries
422
+ version = node .execute ("postgres" , "show server_version_num" )
423
+ if version < 90600 :
424
+ return
425
+
426
+ # Prepare test database
427
+ node .psql ('postgres' , 'create extension pg_pathman' )
428
+ node .psql ('postgres' , 'create table range_partitioned as select generate_series(1, 1e4::integer) i' )
429
+ node .psql ('postgres' , 'alter table range_partitioned alter column i set not null' )
430
+ node .psql ('postgres' , 'select create_range_partitions(\' range_partitioned\' , \' i\' , 1, 1e3::integer)' )
431
+ node .psql ('postgres' , 'vacuum analyze range_partitioned' )
432
+
433
+ node .psql ('postgres' , 'create table hash_partitioned as select generate_series(1, 1e4::integer) i' )
434
+ node .psql ('postgres' , 'alter table hash_partitioned alter column i set not null' )
435
+ node .psql ('postgres' , 'select create_hash_partitions(\' hash_partitioned\' , \' i\' , 10)' )
436
+ node .psql ('postgres' , 'vacuum analyze hash_partitioned' )
437
+
438
+ # Test parallel select
439
+ with node .connect () as con :
440
+ con .execute ('set max_parallel_workers_per_gather = 2' )
441
+ con .execute ('set min_parallel_relation_size = 0' )
442
+ con .execute ('set parallel_setup_cost = 0' )
443
+ con .execute ('set parallel_tuple_cost = 0' )
444
+
445
+ # Check parallel aggregate plan
446
+ plan = con .execute ('explain (costs off) select count(*) from range_partitioned where i < 1500' )
447
+ expected = [('Finalize Aggregate' ,),
448
+ (' -> Gather' ,),
449
+ (' Workers Planned: 2' ,),
450
+ (' -> Partial Aggregate' ,),
451
+ (' -> Append' ,),
452
+ (' -> Parallel Seq Scan on range_partitioned_1' ,),
453
+ (' -> Parallel Seq Scan on range_partitioned_2' ,),
454
+ (' Filter: (i < 1500)' ,)]
455
+ self .assertEqual (plan , expected )
456
+
457
+ # Check count of returned tuples
458
+ count = con .execute ('select count(*) from range_partitioned where i < 1500' )
459
+ self .assertEqual (count [0 ][0 ], 1499 )
460
+
461
+ # Check simple parallel seq scan plan with limit
462
+ plan = con .execute ('explain (costs off) select * from range_partitioned where i < 1500 limit 5' )
463
+ expected = [('Limit' ,),
464
+ (' -> Gather' ,),
465
+ (' Workers Planned: 2' ,),
466
+ (' -> Append' ,),
467
+ (' -> Parallel Seq Scan on range_partitioned_1' ,),
468
+ (' -> Parallel Seq Scan on range_partitioned_2' ,),
469
+ (' Filter: (i < 1500)' ,)]
470
+ self .assertEqual (plan , expected )
471
+
472
+ # Check tuples returned by query above
473
+ res_tuples = con .execute ('select * from range_partitioned where i < 1500 limit 5' )
474
+ expected = [(1 ,), (2 ,), (3 ,), (4 ,), (5 ,)]
475
+ self .assertEqual (res_tuples , expected )
476
+ # import ipdb; ipdb.set_trace()
477
+
478
+ # Remove all objects for testing
479
+ node .psql ('postgres' , 'drop table range_partitioned cascade' )
480
+ node .psql ('postgres' , 'drop table hash_partitioned cascade' )
481
+ node .psql ('postgres' , 'drop extension pg_pathman cascade' )
482
+
483
+ # Stop instance and finish work
484
+ node .stop ()
485
+ node .cleanup ()
486
+
409
487
410
488
if __name__ == "__main__" :
411
489
unittest .main ()
0 commit comments