I want to create a custom hash function that would be used by Postgres (version 13.2) to distribute rows across partitions. Problem is that with the current solution Postgres does not use partition pruning. Here is my code:
-- dummy hash function
CREATE OR REPLACE FUNCTION partition_custom_bigint_hash(value BIGINT, seed
BIGINT)
RETURNS BIGINT AS $$
SELECT value;
$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
-- operator
CREATE OPERATOR CLASS partition_custom_bigint_hash_op
FOR TYPE int8
USING hash AS
OPERATOR 1 =,
FUNCTION 2 partition_custom_bigint_hash(BIGINT, BIGINT);
-- table partitioned by hash with custom operator
CREATE TABLE sample(part_id BIGINT) PARTITION BY hash(part_id partition_custom_bigint_hash_op);
CREATE TABLE sample_part_1 PARTITION OF SAMPLE FOR VALUES WITH (modulus 3, remainder 0);
CREATE TABLE sample_part_2 PARTITION OF SAMPLE FOR VALUES WITH (modulus 3, remainder 1);
CREATE TABLE sample_part_3 PARTITION OF SAMPLE FOR VALUES WITH (modulus 3, remainder 2);
Now make sure that partition pruning is enabled and works correctly:
SHOW enable_partition_pruning;
-- enable_partition_pruning
-- --------------------------
-- on
EXPLAIN * FROM sample WHERE part_id = 1::BIGINT;
-- QUERY PLAN
-- ----------------------------------------------------------------------
-- Seq Scan on sample_part_1 sample (cost=0.00..38.25 rows=11 width=8)
-- Filter: (part_id = '1'::bigint)
-- (2 rows)
So it works fine when using condition part_id=1::BIGINT
but if I skip casting to BIGINT I get:
EXPLAIN SELECT * FROM sample WHERE part_id = 1;
-- QUERY PLAN
-- ------------------------------------------------------------------------------
-- Append (cost=0.00..101.36 rows=33 width=8)
-- -> Seq Scan on sample_part_1 sample_1 (cost=0.00..33.73 rows=11 width=8)
-- Filter: (part_id = 1)
-- -> Seq Scan on sample_part_2 sample_2 (cost=0.00..33.73 rows=11 width=8)
-- Filter: (part_id = 1)
-- -> Seq Scan on sample_part_3 sample_3 (cost=0.00..33.73 rows=11 width=8)
-- Filter: (part_id = 1)
Question: What I need to change in order to make partition pruning work with both conditions part_id=1
and part_id=1::BIGINT
?