@@ -1332,6 +1332,197 @@ explain (costs off) select * from rparted_by_int2 where a > 100000000000000;
13321332
13331333drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2;
13341334--
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+ --
13351526-- Test runtime partition pruning
13361527--
13371528create table ab (a int not null, b int not null) partition by list (a);
0 commit comments