Add DistTableCacheEntry->shardValueCompareFunction.

That's useful when comparing values a hash-partitioned table is
filtered by.  The existing shardIntervalCompareFunction is about
comparing hashed values, not unhashed ones.

The added btree opclass function is so we can get a comparator
back. This should be changed much more widely, but is not necessary so
far.
pull/1331/head
Andres Freund 2017-04-25 23:29:10 -07:00
parent 52571c00ad
commit 105483ec56
4 changed files with 65 additions and 9 deletions

View File

@ -156,6 +156,7 @@ static HeapTuple LookupDistPartitionTuple(Relation pgDistPartition, Oid relation
static List * LookupDistShardTuples(Oid relationId); static List * LookupDistShardTuples(Oid relationId);
static Oid LookupShardRelation(int64 shardId); static Oid LookupShardRelation(int64 shardId);
static void GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod, static void GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod,
Oid *columnTypeId, int32 *columnTypeMod,
Oid *intervalTypeId, int32 *intervalTypeMod); Oid *intervalTypeId, int32 *intervalTypeMod);
static ShardInterval * TupleToShardInterval(HeapTuple heapTuple, static ShardInterval * TupleToShardInterval(HeapTuple heapTuple,
TupleDesc tupleDescriptor, Oid intervalTypeId, TupleDesc tupleDescriptor, Oid intervalTypeId,
@ -617,11 +618,19 @@ BuildCachedShardList(DistTableCacheEntry *cacheEntry)
ShardInterval **shardIntervalArray = NULL; ShardInterval **shardIntervalArray = NULL;
ShardInterval **sortedShardIntervalArray = NULL; ShardInterval **sortedShardIntervalArray = NULL;
FmgrInfo *shardIntervalCompareFunction = NULL; FmgrInfo *shardIntervalCompareFunction = NULL;
FmgrInfo *shardColumnCompareFunction = NULL;
List *distShardTupleList = NIL; List *distShardTupleList = NIL;
int shardIntervalArrayLength = 0; int shardIntervalArrayLength = 0;
int shardIndex = 0; int shardIndex = 0;
Oid columnTypeId = InvalidOid;
int32 columnTypeMod = -1;
Oid intervalTypeId = InvalidOid;
int32 intervalTypeMod = -1;
GetPartitionTypeInputInfo(cacheEntry->partitionKeyString, GetPartitionTypeInputInfo(cacheEntry->partitionKeyString,
cacheEntry->partitionMethod, cacheEntry->partitionMethod,
&columnTypeId,
&columnTypeMod,
&intervalTypeId, &intervalTypeId,
&intervalTypeMod); &intervalTypeMod);
@ -671,7 +680,22 @@ BuildCachedShardList(DistTableCacheEntry *cacheEntry)
heap_close(distShardRelation, AccessShareLock); 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) if (intervalTypeId != InvalidOid)
{ {
/* allocate the comparison function in the cache context */ /* allocate the comparison function in the cache context */
@ -785,6 +809,7 @@ BuildCachedShardList(DistTableCacheEntry *cacheEntry)
cacheEntry->shardIntervalArrayLength = shardIntervalArrayLength; cacheEntry->shardIntervalArrayLength = shardIntervalArrayLength;
cacheEntry->sortedShardIntervalArray = sortedShardIntervalArray; cacheEntry->sortedShardIntervalArray = sortedShardIntervalArray;
cacheEntry->shardColumnCompareFunction = shardColumnCompareFunction;
cacheEntry->shardIntervalCompareFunction = shardIntervalCompareFunction; cacheEntry->shardIntervalCompareFunction = shardIntervalCompareFunction;
} }
@ -2375,8 +2400,11 @@ LookupShardRelation(int64 shardId)
*/ */
static void static void
GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod, GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod,
Oid *columnTypeId, int32 *columnTypeMod,
Oid *intervalTypeId, int32 *intervalTypeMod) Oid *intervalTypeId, int32 *intervalTypeMod)
{ {
*columnTypeId = InvalidOid;
*columnTypeMod = -1;
*intervalTypeId = InvalidOid; *intervalTypeId = InvalidOid;
*intervalTypeMod = -1; *intervalTypeMod = -1;
@ -2391,18 +2419,25 @@ GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod,
*intervalTypeId = partitionColumn->vartype; *intervalTypeId = partitionColumn->vartype;
*intervalTypeMod = partitionColumn->vartypmod; *intervalTypeMod = partitionColumn->vartypmod;
*columnTypeId = partitionColumn->vartype;
*columnTypeMod = partitionColumn->vartypmod;
break; break;
} }
case DISTRIBUTE_BY_HASH: case DISTRIBUTE_BY_HASH:
{ {
Node *partitionNode = stringToNode(partitionKeyString);
Var *partitionColumn = (Var *) partitionNode;
Assert(IsA(partitionNode, Var));
*intervalTypeId = INT4OID; *intervalTypeId = INT4OID;
*columnTypeId = partitionColumn->vartype;
*columnTypeMod = partitionColumn->vartypmod;
break; break;
} }
case DISTRIBUTE_BY_NONE: case DISTRIBUTE_BY_NONE:
{ {
*intervalTypeId = InvalidOid;
break; break;
} }

View File

@ -49,7 +49,15 @@ typedef struct
int shardIntervalArrayLength; int shardIntervalArrayLength;
ShardInterval **sortedShardIntervalArray; 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 */ FmgrInfo *hashFunction; /* NULL if table is not distributed by hash */
/* pg_dist_shard_placement metadata */ /* pg_dist_shard_placement metadata */

View File

@ -10,8 +10,13 @@ CREATE TYPE test_composite_type AS (
); );
-- ... as well as a function to use as its comparator... -- ... 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 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 'internal'
LANGUAGE SQL 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 IMMUTABLE
RETURNS NULL ON NULL INPUT; RETURNS NULL ON NULL INPUT;
-- ... use that function to create a custom equality operator... -- ... 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 -- One uses BTREE the other uses HASH
CREATE OPERATOR CLASS cats_op_fam_clas3 CREATE OPERATOR CLASS cats_op_fam_clas3
DEFAULT FOR TYPE test_composite_type USING BTREE AS 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 CREATE OPERATOR CLASS cats_op_fam_class
DEFAULT FOR TYPE test_composite_type USING HASH AS DEFAULT FOR TYPE test_composite_type USING HASH AS
OPERATOR 1 = (test_composite_type, test_composite_type), OPERATOR 1 = (test_composite_type, test_composite_type),

View File

@ -15,8 +15,14 @@ CREATE TYPE test_composite_type AS (
-- ... as well as a function to use as its comparator... -- ... 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 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 'internal'
LANGUAGE SQL 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 IMMUTABLE
RETURNS NULL ON NULL INPUT; RETURNS NULL ON NULL INPUT;
@ -44,7 +50,8 @@ RETURNS NULL ON NULL INPUT;
-- One uses BTREE the other uses HASH -- One uses BTREE the other uses HASH
CREATE OPERATOR CLASS cats_op_fam_clas3 CREATE OPERATOR CLASS cats_op_fam_clas3
DEFAULT FOR TYPE test_composite_type USING BTREE AS 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 CREATE OPERATOR CLASS cats_op_fam_class
DEFAULT FOR TYPE test_composite_type USING HASH AS DEFAULT FOR TYPE test_composite_type USING HASH AS