aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execPartition.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2022-04-07 23:42:13 +0200
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2022-04-07 23:42:13 +0200
commita90641eac24dfc8889122d88eb7f482cd3db8b39 (patch)
tree2504b842babaeceb8bf9f29a700c27fe5fa6a55d /src/backend/executor/execPartition.c
parent3e707fbb4009e9ac1d0e8b78b7af9f3f03f4cf1a (diff)
downloadpostgresql-a90641eac24dfc8889122d88eb7f482cd3db8b39.tar.gz
postgresql-a90641eac24dfc8889122d88eb7f482cd3db8b39.zip
Revert "Rewrite some RI code to avoid using SPI"
This reverts commit 99392cdd78b788295e52b9f4942fa11992fd5ba9. We'd rather rewrite ri_triggers.c as a whole rather than piecemeal. Discussion: https://postgr.es/m/E1ncXX2-000mFt-Pe@gemulon.postgresql.org
Diffstat (limited to 'src/backend/executor/execPartition.c')
-rw-r--r--src/backend/executor/execPartition.c174
1 files changed, 6 insertions, 168 deletions
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index c22c9ac0966..615bd809735 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -176,9 +176,8 @@ static void FormPartitionKeyDatum(PartitionDispatch pd,
EState *estate,
Datum *values,
bool *isnull);
-static int get_partition_for_tuple(PartitionKey key,
- PartitionDesc partdesc,
- Datum *values, bool *isnull);
+static int get_partition_for_tuple(PartitionDispatch pd, Datum *values,
+ bool *isnull);
static char *ExecBuildSlotPartitionKeyDescription(Relation rel,
Datum *values,
bool *isnull,
@@ -319,9 +318,7 @@ ExecFindPartition(ModifyTableState *mtstate,
* these values, error out.
*/
if (partdesc->nparts == 0 ||
- (partidx = get_partition_for_tuple(dispatch->key,
- dispatch->partdesc,
- values, isnull)) < 0)
+ (partidx = get_partition_for_tuple(dispatch, values, isnull)) < 0)
{
char *val_desc;
@@ -1344,12 +1341,12 @@ FormPartitionKeyDatum(PartitionDispatch pd,
* found or -1 if none found.
*/
static int
-get_partition_for_tuple(PartitionKey key,
- PartitionDesc partdesc,
- Datum *values, bool *isnull)
+get_partition_for_tuple(PartitionDispatch pd, Datum *values, bool *isnull)
{
int bound_offset;
int part_index = -1;
+ PartitionKey key = pd->key;
+ PartitionDesc partdesc = pd->partdesc;
PartitionBoundInfo boundinfo = partdesc->boundinfo;
/* Route as appropriate based on partitioning strategy. */
@@ -1442,165 +1439,6 @@ get_partition_for_tuple(PartitionKey key,
}
/*
- * ExecGetLeafPartitionForKey
- * Finds the leaf partition of partitioned table 'root_rel' that would
- * contain the specified key tuple.
- *
- * A subset of the table's columns (including all of the partition key columns)
- * must be specified:
- * - 'key_natts' indicats the number of columns contained in the key
- * - 'key_attnums' indicates their attribute numbers as defined in 'root_rel'
- * - 'key_vals' and 'key_nulls' specify the key tuple
- *
- * Returns the leaf partition, locked with the given lockmode, or NULL if
- * there isn't one. Caller is responsibly for closing it. All intermediate
- * partitions are also locked with the same lockmode. Caller must have locked
- * the root already.
- *
- * In addition, the OID of the index of a unique constraint on the root table
- * must be given as 'root_idxoid'; *leaf_idxoid will be set to the OID of the
- * corresponding index on the returned leaf partition. (This can be used by
- * caller to search for a tuple matching the key in the leaf partition.)
- *
- * This works because the unique key defined on the root relation is required
- * to contain the partition key columns of all of the ancestors that lead up to
- * a given leaf partition.
- */
-Relation
-ExecGetLeafPartitionForKey(Relation root_rel, int key_natts,
- const AttrNumber *key_attnums,
- Datum *key_vals, char *key_nulls,
- Oid root_idxoid, int lockmode,
- Oid *leaf_idxoid)
-{
- Relation found_leafpart = NULL;
- Relation rel = root_rel;
- Oid constr_idxoid = root_idxoid;
- PartitionDirectory partdir;
-
- Assert(root_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
-
- *leaf_idxoid = InvalidOid;
-
- partdir = CreatePartitionDirectory(CurrentMemoryContext, true);
-
- /*
- * Descend through partitioned parents to find the leaf partition that
- * would accept a row with the provided key values, starting with the root
- * parent.
- */
- for (;;)
- {
- PartitionKey partkey = RelationGetPartitionKey(rel);
- PartitionDesc partdesc;
- Datum partkey_vals[PARTITION_MAX_KEYS];
- bool partkey_isnull[PARTITION_MAX_KEYS];
- AttrNumber *root_partattrs = partkey->partattrs;
- int found_att;
- int partidx;
- Oid partoid;
-
- CHECK_FOR_INTERRUPTS();
-
- /*
- * Collect partition key values from the unique key.
- *
- * Because we only have the root table's copy of pk_attnums, must map
- * any non-root table's partition key attribute numbers to the root
- * table's.
- */
- if (rel != root_rel)
- {
- /*
- * map->attnums will contain root table attribute numbers for each
- * attribute of the current partitioned relation.
- */
- AttrMap *map;
-
- map = build_attrmap_by_name_if_req(RelationGetDescr(root_rel),
- RelationGetDescr(rel));
- if (map)
- {
- root_partattrs = palloc(partkey->partnatts *
- sizeof(AttrNumber));
- for (int att = 0; att < partkey->partnatts; att++)
- {
- AttrNumber partattno = partkey->partattrs[att];
-
- root_partattrs[att] = map->attnums[partattno - 1];
- }
-
- free_attrmap(map);
- }
- }
-
- /*
- * Map the values/isnulls to match the partition description, as
- * necessary.
- *
- * (Referenced key specification does not allow expressions, so there
- * would not be expressions in the partition keys either.)
- */
- Assert(partkey->partexprs == NIL);
- found_att = 0;
- for (int keyatt = 0; keyatt < key_natts; keyatt++)
- {
- for (int att = 0; att < partkey->partnatts; att++)
- {
- if (root_partattrs[att] == key_attnums[keyatt])
- {
- partkey_vals[found_att] = key_vals[keyatt];
- partkey_isnull[found_att] = (key_nulls[keyatt] == 'n');
- found_att++;
- break;
- }
- }
- }
- /* We had better have found values for all partition keys */
- Assert(found_att == partkey->partnatts);
-
- if (root_partattrs != partkey->partattrs)
- pfree(root_partattrs);
-
- /* Get the PartitionDesc using the partition directory machinery. */
- partdesc = PartitionDirectoryLookup(partdir, rel);
- if (partdesc->nparts == 0)
- break;
-
- /* Find the partition for the key. */
- partidx = get_partition_for_tuple(partkey, partdesc,
- partkey_vals, partkey_isnull);
- Assert(partidx < 0 || partidx < partdesc->nparts);
-
- /* close the previous parent if any, but keep lock */
- if (rel != root_rel)
- table_close(rel, NoLock);
-
- /* No partition found. */
- if (partidx < 0)
- break;
-
- partoid = partdesc->oids[partidx];
- rel = table_open(partoid, lockmode);
- constr_idxoid = index_get_partition(rel, constr_idxoid);
-
- /*
- * We're done if the partition is a leaf, else find its partition in
- * the next iteration.
- */
- if (partdesc->is_leaf[partidx])
- {
- *leaf_idxoid = constr_idxoid;
- found_leafpart = rel;
- break;
- }
- }
-
- DestroyPartitionDirectory(partdir);
- return found_leafpart;
-}
-
-/*
* ExecBuildSlotPartitionKeyDescription
*
* This works very much like BuildIndexValueDescription() and is currently