Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a4d56f5

Browse files
committed
Use the right memory context for partkey's FmgrInfo
We were using CurrentMemoryContext to put the partsupfunc fmgr_info into, which isn't right, because we want the PartitionKey as a whole to be in the isolated Relation->rd_partkeycxt context. This can cause a crash with user-defined support functions in the operator classes used by partitioning keys. (Maybe this can cause problems with core-supplied opclasses too, not sure.) This is demonstrably broken in Postgres 10, too, but the initial proposed fix runs afoul of a problem discussed back when 8a0596c ("Get rid of copy_partition_key") reorganized that code: namely that it is possible to jump out of RelationBuildPartitionKey because of some error and leave a dangling memory context child of CacheMemoryContext. Also, while reviewing this I noticed that the removed-in-pg11 copy_partition_key was doing something wrong, unfixed in pg10, namely doing memcpy() on the FmgrInfo, which is bogus (should be doing fmgr_info_copy). Therefore, in branch pg10, the sane fix seems to be to backpatch both the aforementioned 8a0596c and its followup be23432 ("Protect against hypothetical memory leaks in RelationGetPartitionKey"), so do that, then apply the fmgr_info memcxt bugfix on top. Add a test case exercising btree-based custom operator classes, which causes a crash prior to this fix. This is not a security problem, because in order to create an operator class you need superuser privileges anyway. Authors: Álvaro Herrera and Amit Langote Reported and diagnosed by: Amit Langote Discussion: https://postgr.es/m/3041e853-b1dd-a0c6-ff21-7cc5633bffd0@lab.ntt.co.jp
1 parent 3e110a3 commit a4d56f5

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

src/backend/utils/cache/relcache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ RelationBuildPartitionKey(Relation relation)
10341034
procnum,
10351035
format_type_be(opclassform->opcintype))));
10361036

1037-
fmgr_info(funcid, &key->partsupfunc[i]);
1037+
fmgr_info_cxt(funcid, &key->partsupfunc[i], partkeycxt);
10381038

10391039
/* Collation */
10401040
key->partcollation[i] = collation->values[i];

src/test/regress/expected/create_table.out

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -837,10 +837,22 @@ Partition of: range_parted4 FOR VALUES FROM (6, 8, MINVALUE) TO (9, MAXVALUE, MA
837837
Partition constraint: ((abs(a) IS NOT NULL) AND (abs(b) IS NOT NULL) AND (c IS NOT NULL) AND ((abs(a) > 6) OR ((abs(a) = 6) AND (abs(b) >= 8))) AND (abs(a) <= 9))
838838

839839
DROP TABLE range_parted4;
840+
-- user-defined operator class in partition key
841+
CREATE FUNCTION my_int4_sort(int4,int4) RETURNS int LANGUAGE sql
842+
AS $$ SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$;
843+
CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS
844+
OPERATOR 1 < (int4,int4), OPERATOR 2 <= (int4,int4),
845+
OPERATOR 3 = (int4,int4), OPERATOR 4 >= (int4,int4),
846+
OPERATOR 5 > (int4,int4), FUNCTION 1 my_int4_sort(int4,int4);
847+
CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops);
848+
CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000);
849+
INSERT INTO partkey_t VALUES (100);
850+
INSERT INTO partkey_t VALUES (200);
840851
-- cleanup
841852
DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3;
842-
DROP TABLE hash_parted;
843-
DROP TABLE hash_parted2;
853+
DROP TABLE partkey_t, hash_parted, hash_parted2;
854+
DROP OPERATOR CLASS test_int4_ops USING btree;
855+
DROP FUNCTION my_int4_sort(int4,int4);
844856
-- comments on partitioned tables columns
845857
CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a);
846858
COMMENT ON TABLE parted_col_comment IS 'Am partitioned table';

src/test/regress/sql/create_table.sql

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,10 +688,23 @@ CREATE TABLE range_parted4_3 PARTITION OF range_parted4 FOR VALUES FROM (6, 8, M
688688
\d+ range_parted4_3
689689
DROP TABLE range_parted4;
690690

691+
-- user-defined operator class in partition key
692+
CREATE FUNCTION my_int4_sort(int4,int4) RETURNS int LANGUAGE sql
693+
AS $$ SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$;
694+
CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS
695+
OPERATOR 1 < (int4,int4), OPERATOR 2 <= (int4,int4),
696+
OPERATOR 3 = (int4,int4), OPERATOR 4 >= (int4,int4),
697+
OPERATOR 5 > (int4,int4), FUNCTION 1 my_int4_sort(int4,int4);
698+
CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops);
699+
CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000);
700+
INSERT INTO partkey_t VALUES (100);
701+
INSERT INTO partkey_t VALUES (200);
702+
691703
-- cleanup
692704
DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3;
693-
DROP TABLE hash_parted;
694-
DROP TABLE hash_parted2;
705+
DROP TABLE partkey_t, hash_parted, hash_parted2;
706+
DROP OPERATOR CLASS test_int4_ops USING btree;
707+
DROP FUNCTION my_int4_sort(int4,int4);
695708

696709
-- comments on partitioned tables columns
697710
CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a);

0 commit comments

Comments
 (0)