diff --git a/src/backend/distributed/utils/metadata_cache.c b/src/backend/distributed/utils/metadata_cache.c index 710526aaa..a36dd5c46 100644 --- a/src/backend/distributed/utils/metadata_cache.c +++ b/src/backend/distributed/utils/metadata_cache.c @@ -156,6 +156,7 @@ static HeapTuple LookupDistPartitionTuple(Relation pgDistPartition, Oid relation static List * LookupDistShardTuples(Oid relationId); static Oid LookupShardRelation(int64 shardId); static void GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod, + Oid *columnTypeId, int32 *columnTypeMod, Oid *intervalTypeId, int32 *intervalTypeMod); static ShardInterval * TupleToShardInterval(HeapTuple heapTuple, TupleDesc tupleDescriptor, Oid intervalTypeId, @@ -617,11 +618,19 @@ BuildCachedShardList(DistTableCacheEntry *cacheEntry) ShardInterval **shardIntervalArray = NULL; ShardInterval **sortedShardIntervalArray = NULL; FmgrInfo *shardIntervalCompareFunction = NULL; + FmgrInfo *shardColumnCompareFunction = NULL; List *distShardTupleList = NIL; int shardIntervalArrayLength = 0; int shardIndex = 0; + Oid columnTypeId = InvalidOid; + int32 columnTypeMod = -1; + Oid intervalTypeId = InvalidOid; + int32 intervalTypeMod = -1; + GetPartitionTypeInputInfo(cacheEntry->partitionKeyString, cacheEntry->partitionMethod, + &columnTypeId, + &columnTypeMod, &intervalTypeId, &intervalTypeMod); @@ -671,7 +680,22 @@ BuildCachedShardList(DistTableCacheEntry *cacheEntry) heap_close(distShardRelation, AccessShareLock); } - /* decide and allocate interval comparison function */ + /* look up value comparison function */ + if (columnTypeId != InvalidOid) + { + /* allocate the comparison function in the cache context */ + MemoryContext oldContext = MemoryContextSwitchTo(CacheMemoryContext); + + shardColumnCompareFunction = GetFunctionInfo(columnTypeId, BTREE_AM_OID, + BTORDER_PROC); + MemoryContextSwitchTo(oldContext); + } + else + { + shardColumnCompareFunction = NULL; + } + + /* look up interval comparison function */ if (intervalTypeId != InvalidOid) { /* allocate the comparison function in the cache context */ @@ -785,6 +809,7 @@ BuildCachedShardList(DistTableCacheEntry *cacheEntry) cacheEntry->shardIntervalArrayLength = shardIntervalArrayLength; cacheEntry->sortedShardIntervalArray = sortedShardIntervalArray; + cacheEntry->shardColumnCompareFunction = shardColumnCompareFunction; cacheEntry->shardIntervalCompareFunction = shardIntervalCompareFunction; } @@ -2375,8 +2400,11 @@ LookupShardRelation(int64 shardId) */ static void GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod, + Oid *columnTypeId, int32 *columnTypeMod, Oid *intervalTypeId, int32 *intervalTypeMod) { + *columnTypeId = InvalidOid; + *columnTypeMod = -1; *intervalTypeId = InvalidOid; *intervalTypeMod = -1; @@ -2391,18 +2419,25 @@ GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod, *intervalTypeId = partitionColumn->vartype; *intervalTypeMod = partitionColumn->vartypmod; + *columnTypeId = partitionColumn->vartype; + *columnTypeMod = partitionColumn->vartypmod; break; } case DISTRIBUTE_BY_HASH: { + Node *partitionNode = stringToNode(partitionKeyString); + Var *partitionColumn = (Var *) partitionNode; + Assert(IsA(partitionNode, Var)); + *intervalTypeId = INT4OID; + *columnTypeId = partitionColumn->vartype; + *columnTypeMod = partitionColumn->vartypmod; break; } case DISTRIBUTE_BY_NONE: { - *intervalTypeId = InvalidOid; break; } diff --git a/src/include/distributed/metadata_cache.h b/src/include/distributed/metadata_cache.h index d80b4a038..5cc2bbf26 100644 --- a/src/include/distributed/metadata_cache.h +++ b/src/include/distributed/metadata_cache.h @@ -49,7 +49,15 @@ typedef struct int shardIntervalArrayLength; ShardInterval **sortedShardIntervalArray; - FmgrInfo *shardIntervalCompareFunction; /* NULL if DISTRIBUTE_BY_NONE */ + /* comparator for partition column's type, NULL if DISTRIBUTE_BY_NONE */ + FmgrInfo *shardColumnCompareFunction; + + /* + * Comparator for partition interval type (different from + * shardValueCompareFunction if hash-partitioned), NULL if + * DISTRIBUTE_BY_NONE. + */ + FmgrInfo *shardIntervalCompareFunction; FmgrInfo *hashFunction; /* NULL if table is not distributed by hash */ /* pg_dist_shard_placement metadata */ diff --git a/src/test/regress/expected/multi_data_types.out b/src/test/regress/expected/multi_data_types.out index 76fd44367..1cb4d1f9b 100644 --- a/src/test/regress/expected/multi_data_types.out +++ b/src/test/regress/expected/multi_data_types.out @@ -10,8 +10,13 @@ CREATE TYPE test_composite_type AS ( ); -- ... as well as a function to use as its comparator... CREATE FUNCTION equal_test_composite_type_function(test_composite_type, test_composite_type) RETURNS boolean -AS 'select $1.i = $2.i AND $1.i2 = $2.i2;' -LANGUAGE SQL +LANGUAGE 'internal' +AS 'record_eq' +IMMUTABLE +RETURNS NULL ON NULL INPUT; +CREATE FUNCTION cmp_test_composite_type_function(test_composite_type, test_composite_type) RETURNS int +LANGUAGE 'internal' +AS 'btrecordcmp' IMMUTABLE RETURNS NULL ON NULL INPUT; -- ... use that function to create a custom equality operator... @@ -34,7 +39,8 @@ RETURNS NULL ON NULL INPUT; -- One uses BTREE the other uses HASH CREATE OPERATOR CLASS cats_op_fam_clas3 DEFAULT FOR TYPE test_composite_type USING BTREE AS -OPERATOR 3 = (test_composite_type, test_composite_type); +OPERATOR 3 = (test_composite_type, test_composite_type), +FUNCTION 1 cmp_test_composite_type_function(test_composite_type, test_composite_type); CREATE OPERATOR CLASS cats_op_fam_class DEFAULT FOR TYPE test_composite_type USING HASH AS OPERATOR 1 = (test_composite_type, test_composite_type), diff --git a/src/test/regress/sql/multi_data_types.sql b/src/test/regress/sql/multi_data_types.sql index 315550474..3dd6eb0f7 100644 --- a/src/test/regress/sql/multi_data_types.sql +++ b/src/test/regress/sql/multi_data_types.sql @@ -15,8 +15,14 @@ CREATE TYPE test_composite_type AS ( -- ... as well as a function to use as its comparator... CREATE FUNCTION equal_test_composite_type_function(test_composite_type, test_composite_type) RETURNS boolean -AS 'select $1.i = $2.i AND $1.i2 = $2.i2;' -LANGUAGE SQL +LANGUAGE 'internal' +AS 'record_eq' +IMMUTABLE +RETURNS NULL ON NULL INPUT; + +CREATE FUNCTION cmp_test_composite_type_function(test_composite_type, test_composite_type) RETURNS int +LANGUAGE 'internal' +AS 'btrecordcmp' IMMUTABLE RETURNS NULL ON NULL INPUT; @@ -44,7 +50,8 @@ RETURNS NULL ON NULL INPUT; -- One uses BTREE the other uses HASH CREATE OPERATOR CLASS cats_op_fam_clas3 DEFAULT FOR TYPE test_composite_type USING BTREE AS -OPERATOR 3 = (test_composite_type, test_composite_type); +OPERATOR 3 = (test_composite_type, test_composite_type), +FUNCTION 1 cmp_test_composite_type_function(test_composite_type, test_composite_type); CREATE OPERATOR CLASS cats_op_fam_class DEFAULT FOR TYPE test_composite_type USING HASH AS