@@ -1332,6 +1332,197 @@ explain (costs off) select * from rparted_by_int2 where a > 100000000000000;
1332
1332
1333
1333
drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2;
1334
1334
--
1335
+ -- Test Partition pruning for HASH partitioning
1336
+ --
1337
+ -- Use hand-rolled hash functions and operator classes to get predictable
1338
+ -- result on different matchines. See the definitions of
1339
+ -- part_part_test_int4_ops and part_test_text_ops in insert.sql.
1340
+ --
1341
+ create table hp (a int, b text) partition by hash (a part_test_int4_ops, b part_test_text_ops);
1342
+ create table hp0 partition of hp for values with (modulus 4, remainder 0);
1343
+ create table hp3 partition of hp for values with (modulus 4, remainder 3);
1344
+ create table hp1 partition of hp for values with (modulus 4, remainder 1);
1345
+ create table hp2 partition of hp for values with (modulus 4, remainder 2);
1346
+ insert into hp values (null, null);
1347
+ insert into hp values (1, null);
1348
+ insert into hp values (1, 'xxx');
1349
+ insert into hp values (null, 'xxx');
1350
+ insert into hp values (2, 'xxx');
1351
+ insert into hp values (1, 'abcde');
1352
+ select tableoid::regclass, * from hp order by 1;
1353
+ tableoid | a | b
1354
+ ----------+---+-------
1355
+ hp0 | |
1356
+ hp0 | 1 | xxx
1357
+ hp3 | 2 | xxx
1358
+ hp1 | 1 |
1359
+ hp2 | | xxx
1360
+ hp2 | 1 | abcde
1361
+ (6 rows)
1362
+
1363
+ -- partial keys won't prune, nor would non-equality conditions
1364
+ explain (costs off) select * from hp where a = 1;
1365
+ QUERY PLAN
1366
+ -------------------------
1367
+ Append
1368
+ -> Seq Scan on hp0
1369
+ Filter: (a = 1)
1370
+ -> Seq Scan on hp1
1371
+ Filter: (a = 1)
1372
+ -> Seq Scan on hp2
1373
+ Filter: (a = 1)
1374
+ -> Seq Scan on hp3
1375
+ Filter: (a = 1)
1376
+ (9 rows)
1377
+
1378
+ explain (costs off) select * from hp where b = 'xxx';
1379
+ QUERY PLAN
1380
+ -----------------------------------
1381
+ Append
1382
+ -> Seq Scan on hp0
1383
+ Filter: (b = 'xxx'::text)
1384
+ -> Seq Scan on hp1
1385
+ Filter: (b = 'xxx'::text)
1386
+ -> Seq Scan on hp2
1387
+ Filter: (b = 'xxx'::text)
1388
+ -> Seq Scan on hp3
1389
+ Filter: (b = 'xxx'::text)
1390
+ (9 rows)
1391
+
1392
+ explain (costs off) select * from hp where a is null;
1393
+ QUERY PLAN
1394
+ -----------------------------
1395
+ Append
1396
+ -> Seq Scan on hp0
1397
+ Filter: (a IS NULL)
1398
+ -> Seq Scan on hp1
1399
+ Filter: (a IS NULL)
1400
+ -> Seq Scan on hp2
1401
+ Filter: (a IS NULL)
1402
+ -> Seq Scan on hp3
1403
+ Filter: (a IS NULL)
1404
+ (9 rows)
1405
+
1406
+ explain (costs off) select * from hp where b is null;
1407
+ QUERY PLAN
1408
+ -----------------------------
1409
+ Append
1410
+ -> Seq Scan on hp0
1411
+ Filter: (b IS NULL)
1412
+ -> Seq Scan on hp1
1413
+ Filter: (b IS NULL)
1414
+ -> Seq Scan on hp2
1415
+ Filter: (b IS NULL)
1416
+ -> Seq Scan on hp3
1417
+ Filter: (b IS NULL)
1418
+ (9 rows)
1419
+
1420
+ explain (costs off) select * from hp where a < 1 and b = 'xxx';
1421
+ QUERY PLAN
1422
+ -------------------------------------------------
1423
+ Append
1424
+ -> Seq Scan on hp0
1425
+ Filter: ((a < 1) AND (b = 'xxx'::text))
1426
+ -> Seq Scan on hp1
1427
+ Filter: ((a < 1) AND (b = 'xxx'::text))
1428
+ -> Seq Scan on hp2
1429
+ Filter: ((a < 1) AND (b = 'xxx'::text))
1430
+ -> Seq Scan on hp3
1431
+ Filter: ((a < 1) AND (b = 'xxx'::text))
1432
+ (9 rows)
1433
+
1434
+ explain (costs off) select * from hp where a <> 1 and b = 'yyy';
1435
+ QUERY PLAN
1436
+ --------------------------------------------------
1437
+ Append
1438
+ -> Seq Scan on hp0
1439
+ Filter: ((a <> 1) AND (b = 'yyy'::text))
1440
+ -> Seq Scan on hp1
1441
+ Filter: ((a <> 1) AND (b = 'yyy'::text))
1442
+ -> Seq Scan on hp2
1443
+ Filter: ((a <> 1) AND (b = 'yyy'::text))
1444
+ -> Seq Scan on hp3
1445
+ Filter: ((a <> 1) AND (b = 'yyy'::text))
1446
+ (9 rows)
1447
+
1448
+ explain (costs off) select * from hp where a <> 1 and b <> 'xxx';
1449
+ QUERY PLAN
1450
+ ---------------------------------------------------
1451
+ Append
1452
+ -> Seq Scan on hp0
1453
+ Filter: ((a <> 1) AND (b <> 'xxx'::text))
1454
+ -> Seq Scan on hp1
1455
+ Filter: ((a <> 1) AND (b <> 'xxx'::text))
1456
+ -> Seq Scan on hp2
1457
+ Filter: ((a <> 1) AND (b <> 'xxx'::text))
1458
+ -> Seq Scan on hp3
1459
+ Filter: ((a <> 1) AND (b <> 'xxx'::text))
1460
+ (9 rows)
1461
+
1462
+ -- pruning should work if either a value or a IS NULL clause is provided for
1463
+ -- each of the keys
1464
+ explain (costs off) select * from hp where a is null and b is null;
1465
+ QUERY PLAN
1466
+ -----------------------------------------------
1467
+ Append
1468
+ -> Seq Scan on hp0
1469
+ Filter: ((a IS NULL) AND (b IS NULL))
1470
+ (3 rows)
1471
+
1472
+ explain (costs off) select * from hp where a = 1 and b is null;
1473
+ QUERY PLAN
1474
+ -------------------------------------------
1475
+ Append
1476
+ -> Seq Scan on hp1
1477
+ Filter: ((b IS NULL) AND (a = 1))
1478
+ (3 rows)
1479
+
1480
+ explain (costs off) select * from hp where a = 1 and b = 'xxx';
1481
+ QUERY PLAN
1482
+ -------------------------------------------------
1483
+ Append
1484
+ -> Seq Scan on hp0
1485
+ Filter: ((a = 1) AND (b = 'xxx'::text))
1486
+ (3 rows)
1487
+
1488
+ explain (costs off) select * from hp where a is null and b = 'xxx';
1489
+ QUERY PLAN
1490
+ -----------------------------------------------------
1491
+ Append
1492
+ -> Seq Scan on hp2
1493
+ Filter: ((a IS NULL) AND (b = 'xxx'::text))
1494
+ (3 rows)
1495
+
1496
+ explain (costs off) select * from hp where a = 2 and b = 'xxx';
1497
+ QUERY PLAN
1498
+ -------------------------------------------------
1499
+ Append
1500
+ -> Seq Scan on hp3
1501
+ Filter: ((a = 2) AND (b = 'xxx'::text))
1502
+ (3 rows)
1503
+
1504
+ explain (costs off) select * from hp where a = 1 and b = 'abcde';
1505
+ QUERY PLAN
1506
+ ---------------------------------------------------
1507
+ Append
1508
+ -> Seq Scan on hp2
1509
+ Filter: ((a = 1) AND (b = 'abcde'::text))
1510
+ (3 rows)
1511
+
1512
+ explain (costs off) select * from hp where (a = 1 and b = 'abcde') or (a = 2 and b = 'xxx') or (a is null and b is null);
1513
+ QUERY PLAN
1514
+ -------------------------------------------------------------------------------------------------------------------------
1515
+ Append
1516
+ -> Seq Scan on hp0
1517
+ Filter: (((a = 1) AND (b = 'abcde'::text)) OR ((a = 2) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL)))
1518
+ -> Seq Scan on hp2
1519
+ Filter: (((a = 1) AND (b = 'abcde'::text)) OR ((a = 2) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL)))
1520
+ -> Seq Scan on hp3
1521
+ Filter: (((a = 1) AND (b = 'abcde'::text)) OR ((a = 2) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL)))
1522
+ (7 rows)
1523
+
1524
+ drop table hp;
1525
+ --
1335
1526
-- Test runtime partition pruning
1336
1527
--
1337
1528
create table ab (a int not null, b int not null) partition by list (a);
0 commit comments