MCPcopy Create free account
hub / github.com/apache/cloudberry / get_partition_for_tuple

Function get_partition_for_tuple

src/backend/executor/execPartition.c:1361–1572  ·  view source on GitHub ↗

* get_partition_for_tuple * Finds partition of relation which accepts the partition key specified * in values and isnull. * * Calling this function can be quite expensive when LIST and RANGE * partitioned tables have many partitions. This is due to the binary search * that's done to find the correct partition. Many of the use cases for LIST * and RANGE partitioned tables make it likely

Source from the content-addressed store, hash-verified

1359 * found or -1 if none found.
1360 */
1361int
1362get_partition_for_tuple(PartitionKey key, PartitionDesc partdesc, Datum *values, bool *isnull)
1363{
1364 int bound_offset = -1;
1365 int part_index = -1;
1366 PartitionBoundInfo boundinfo = partdesc->boundinfo;
1367
1368 if (partdesc->nparts == 0)
1369 return part_index;
1370 /*
1371 * In the switch statement below, when we perform a cached lookup for
1372 * RANGE and LIST partitioned tables, if we find that the last found
1373 * partition matches the 'values', we return the partition index right
1374 * away. We do this instead of breaking out of the switch as we don't
1375 * want to execute the code about the DEFAULT partition or do any updates
1376 * for any of the cache-related fields. That would be a waste of effort
1377 * as we already know it's not the DEFAULT partition and have no need to
1378 * increment the number of times we found the same partition any higher
1379 * than PARTITION_CACHED_FIND_THRESHOLD.
1380 */
1381
1382 /* Route as appropriate based on partitioning strategy. */
1383 switch (key->strategy)
1384 {
1385 case PARTITION_STRATEGY_HASH:
1386 {
1387 uint64 rowHash;
1388
1389 /* hash partitioning is too cheap to bother caching */
1390 rowHash = compute_partition_hash_value(key->partnatts,
1391 key->partsupfunc,
1392 key->partcollation,
1393 values, isnull);
1394
1395 /*
1396 * HASH partitions can't have a DEFAULT partition and we don't
1397 * do any caching work for them, so just return the part index
1398 */
1399 return boundinfo->indexes[rowHash % boundinfo->nindexes];
1400 }
1401
1402 case PARTITION_STRATEGY_LIST:
1403 if (isnull[0])
1404 {
1405 /* this is far too cheap to bother doing any caching */
1406 if (partition_bound_accepts_nulls(boundinfo))
1407 {
1408 /*
1409 * When there is a NULL partition we just return that
1410 * directly. We don't have a bound_offset so it's not
1411 * valid to drop into the code after the switch which
1412 * checks and updates the cache fields. We perhaps should
1413 * be invalidating the details of the last cached
1414 * partition but there's no real need to. Keeping those
1415 * fields set gives a chance at matching to the cached
1416 * partition on the next lookup.
1417 */
1418 return boundinfo->null_index;

Callers 2

GpFindTargetPartitionFunction · 0.85
ExecFindPartitionFunction · 0.85

Calls 6

DatumGetInt32Function · 0.85
FunctionCall2CollFunction · 0.85
partition_list_bsearchFunction · 0.85

Tested by

no test coverage detected