Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the partition key function to get Tuple in PostgreSQL

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces "what is the partition key function of obtaining Tuple in PostgreSQL". In the daily operation, I believe that many people have doubts about what the partition key function of Tuple is in PostgreSQL. Xiaobian consulted all kinds of data and sorted out a simple and easy-to-use method of operation. I hope it will be helpful for everyone to answer the question of "what is the partition key function of Tuple in PostgreSQL?" Next, please follow the editor to study!

I. data structure

ModifyTable

Apply the rows generated by the subplan to the result table by inserting, updating, or deleting.

/ *-* ModifyTable node-* Apply rows produced by subplan (s) to result table (s), * by inserting, updating, or deleting. * apply the rows generated by the subplan to the result table by inserting, updating, or deleting. * * If the originally named target table is a partitioned table, both * nominalRelation and rootRelation contain the RT index of the partition * root, which is not otherwise mentioned in the plan. Otherwise rootRelation * is zero. However, nominalRelation will always be set, as it's the rel that * EXPLAIN should claim is the INSERT/UPDATE/DELETE target. * if the originally named target table is a partitioned table, both nominalRelation and rootRelation contain the RT index of the partitioned root, which is not mentioned separately in the plan. * otherwise, the root relationship is zero. However, a nominal relationship is always set, nominalRelation because the rel that EXPLAIN should declare is an INSERT/UPDATE/DELETE target relationship. * * Note that rowMarks and epqParam are presumed to be valid for all the * subplan (s); they can't contain any info that varies across subplans. * Note that rowMarks and epqParam are assumed to be valid for all subplans; * they cannot contain any information that changes in the subplan. *-* / typedef struct ModifyTable {Plan plan; CmdType operation; / * operation type; do you need to set tag?do we set the command tag/es_processed for INSERT, UPDATE, or DELETE * / bool canSetTag; / *? * / Index nominalRelation; / * for the parent RT index of EXPLAIN Parent RT index for use of EXPLAIN * / Index rootRelation; / * Root Root RT index (if the target is a partitioned table); Root RT index, if target is partitioned * / bool partColsUpdated; / * updated the partitioning keyword in the hierarchy; some part key in hierarchy updated * / List * resultRelations; / * RT index integer linked list; integer list of RT indexes * / int resultRelIndex / * Index of the first resultRel in the planned linked list; index of first resultRel in plan's list * / int rootResultRelIndex; / * partitioned table root index; index of the partitioned table root * / List * plans; / * generate the planned linked list of the source data; plan (s) producing source data * / List * withCheckOptionLists; / * the WCO linked list that each target table has Per-target-table WCO lists * / List * returningLists; / * RETURNING linked list for each target table; per-target-table RETURNING tlists * / List * fdwPrivLists; / * FDW private data linked list for each target table; per-target-table FDW private data lists * / Bitmapset * fdwDirectModifyPlans; / * FDW DM plan index bitmap; indices of FDW DM plans * / List * rowMarks; / * rowMarks linked list PlanRowMarks (non-locking only) * / int epqParam; / * EvalPlanQual parses the parameter ID;ID of Param for EvalPlanQual re-eval * / OnConflictAction onConflictAction; / * ON CONFLICT action * / List * arbiterIndexes; / * conflict arbiter index table; List of ON CONFLICT arbiter index OIDs * / List * onConflictSet; / * SET for INSERT ON CONFLICT DO UPDATE * / Node * onConflictWhere / * WHERE for ON CONFLICT UPDATE * / Index exclRelRTI; / * RTI of the EXCLUDED pseudo relation * / List * exclRelTlist; / * projection list with pseudo relations excluded; tlist of the EXCLUDED pseudo relation * /} ModifyTable

ResultRelInfo

ResultRelInfo structure

Whenever we update an existing relationship, we must update the index on the relationship and perhaps trigger the trigger. ResultRelInfo holds all the information needed about the result relationship, including the index.

/ * * ResultRelInfo * ResultRelInfo structure * * Whenever we update an existing relation, we have to update indexes on the * relation, and perhaps also fire triggers. ResultRelInfo holds all the * information needed about a result relation, including indexes. * whenever we update an existing relationship, we must update the index on the relationship and perhaps trigger the trigger. * ResultRelInfo keeps all the information needed about the result relationship, including the index. * * Normally, a ResultRelInfo refers to a table that is in the query's * range table; then ri_RangeTableIndex is the RT index and ri_RelationDesc * is just a copy of the relevant es_relations [] entry. But sometimes, * in ResultRelInfos used only for triggers, ri_RangeTableIndex is zero * and ri_RelationDesc is a separately-opened relcache pointer that needs * to be separately closed. See ExecGetTriggerResultRel. * generally, ResultRelInfo refers to the table in the query scope table; * ri_RangeTableIndex is the RT index, and ri_RelationDesc is just a copy of the related es_relations [] entries. * but sometimes, in ResultRelInfos used only for triggers, ri_RangeTableIndex is zero (NULL), and ri_RelationDesc is a relcache pointer that needs to be closed and opened separately. * for more information, please see ExecGetTriggerResultRel structure. * / typedef struct ResultRelInfo {NodeTag type; / * result relation's range table index, or 0 if not in range table * / / RTE index Index ri_RangeTableIndex; / * relation descriptor for result relation * / / result / descriptor of the target relation Relation ri_RelationDesc; / * # of indices existing on result relation * / / number of indexes in the target relationship int ri_NumIndices / * array of relation descriptors for indices * / / the relational descriptor array of the index (the index is regarded as a relation) RelationPtr ri_IndexRelationDescs; / * array of key/attr info for indices * / / the key / attribute array of the index IndexInfo * * ri_IndexRelationInfo; / * triggers to be fired, if any * / / triggered index TriggerDesc * ri_TrigDesc / * cached lookup info for trigger functions * / / trigger function (cache) FmgrInfo * ri_TrigFunctions; / * array of trigger WHEN expr states * / / trigger array of WHEN expression status ExprState * * ri_TrigWhenExprs; / * optional runtime measurements for triggers * / / optional trigger runtime metric Instrumentation * ri_TrigInstrument / * FDW callback functions, if foreign table * / / FDW callback function struct FdwRoutine * ri_FdwRoutine; / * available to save private state of FDW * / / can be used to store the private status of FDW void * ri_FdwState; / * true when modifying foreign table directly * / T bool ri_usesFdwDirectModify when updating FDW directly / * list of WithCheckOption's to be checked * / / WithCheckOption linked list List * ri_WithCheckOptions; / * list of WithCheckOption expr states * / / WithCheckOption expression linked list List * ri_WithCheckOptionExprs; / * array of constraint-checking expr states * / / constraint check expression status array ExprState * * ri_ConstraintExprs / * for removing junk attributes from tuples * / / used to remove junk attributes from the tuple JunkFilter * ri_junkFilter; / * list of RETURNING expressions * / / RETURNING expression linked list List * ri_returningList; / * for computing a RETURNING list * / / used to calculate RETURNING linked list ProjectionInfo * ri_projectReturning / * list of arbiter indexes to use to check conflicts * / / list used to check conflicting arbitrator indexes List * ri_onConflictArbiterIndexes; / * ON CONFLICT evaluation state * / / ON CONFLICT parsing status OnConflictSetState * ri_onConflict; / * partition check expression * / / Partition check expression linked list List * ri_PartitionCheck / * partition check expression state * / / Partition check expression status ExprState * ri_PartitionCheckExpr; / * relation descriptor for root partitioned table * / / Partition root root table descriptor Relation ri_PartitionRoot; / * Additional information specific to partition tuple routing * / additional partition tuple routing information struct PartitionRoutingInfo * ri_PartitionInfo;} ResultRelInfo

PartitionRoutingInfo

PartitionRoutingInfo structure

Partition routing information, which is used to route tuples to the result relationship information of the table partition.

/ * * PartitionRoutingInfo * PartitionRoutingInfo-Partition routing information * * Additional result relation information specific to routing tuples to a * table partition. * result relationship information used to route tuples to table partitions. * / typedef struct PartitionRoutingInfo {/ * * Map for converting tuples in root partitioned table format into * partition format, or NULL if no conversion is required. * mapping, which is used to convert tuples in root partition table format to partition format, or to NULL if no conversion is required. * / TupleConversionMap * pi_RootToPartitionMap; / * * Map for converting tuples in partition format into the root partitioned * table format, or NULL if no conversion is required. * mapping, which is used to convert tuples in partition format to root partition table format, or to NULL if no conversion is required. * / TupleConversionMap * pi_PartitionToRootMap; / * * Slot to store tuples in partition format, or NULL when no translation * is required between root and partition. * store the slot of the tuple in partition format. NULL when no conversion is required between the root partition and the partition. * / TupleTableSlot * pi_PartitionTupleSlot;} PartitionRoutingInfo

TupleConversionMap

TupleConversionMap structure, which is used to store tuple transformation mapping information.

Typedef struct TupleConversionMap {TupleDesc indesc; / * descriptor of source line type; descriptor of tupdesc for source rowtype * / TupleDesc outdesc; / * result line type; index information of tupdesc for result rowtype * / AttrNumber * attrMap; / * input field. 0 represents NULL;indexes of input fields, or 0 for null * / Datum * invalues; / * destructs the workspace of source data Whether workspace for deconstructing source * / bool * inisnull; / / is the workspace of the construction result of NULL tag array Datum * outvalues; / *; workspace for constructing result * / bool * outisnull; / / null tag} TupleConversionMap; II. Source code interpretation

The FormPartitionKeyDatum function gets the partition key of Tuple, returns the values [] array of key values and whether or not to mark the isnull [] array for null.

/ *-* FormPartitionKeyDatum * Construct values [] and isnull [] arrays for the partition key * of a tuple. * construct the partition dispenser (dispatch) object of values [] array and isnull [] array * * pd Partition dispatch object of the partitioned table * pd partition table * * slot Heap tuple from which to extract partition key * slot heap tuple * * estate executor state for evaluating any partition key * from which the partition key is advanced Expressions (must be non-NULL) * estate parses the actuator state of the partition key expression (must be non-NULL) * * values Array of partition key Datums (output area) * partition key Datums array (output parameter) * isnull Array of is-null indicators (output area) * is-null tag Array (output parameters) * * the ecxt_scantuple slot of estate's per-tuple expr context must point to * the heap tuple passed in. * the ecxt_scantuple of the per-tuple context of estate must point to the incoming heap tuple *-* / static voidFormPartitionKeyDatum (PartitionDispatch pd, TupleTableSlot * slot, EState * estate, Datum * values, bool * isnull) {ListCell * partexpr_item; int I If (pd- > key- > partexprs! = NIL & & pd- > keystate = = NIL) {/ * Check caller has set up context correctly * / / check whether the caller has configured the memory context Assert correctly (estate! = NULL & & GetPerTupleExprContext (estate)-> ecxt_scantuple = = slot) / * First time through, set up expression evaluation state * / / enter for the first time, configure expression parser status pd- > keystate = ExecPrepareExprList (pd- > key- > partexprs, estate);} partexpr_item = list_head (pd- > keystate); / / get partition key expression status for (I = 0; I

< pd->

Key- > partnatts; iTunes +) / / Loop through the partition key {AttrNumber keycol = pd- > key- > partattrs [I]; / / Partition key attribute number Datum datum;// typedef uintptr_t Datum;sizeof (Datum) = = sizeof (void *) = = 4 or 8 whether null if (keycol! = 0) / / the number is not 0 {/ * Plain column Get the value directly from the heap tuple * / / flat column, extract the value datum = slot_getattr (slot, keycol, & isNull) directly from the heap tuple;} else {/ * Expression Need to evaluate it * / / expression, need to parse if (partexpr_item = = NULL) / / Partition key expression status is NULL, error elog (ERROR, "wrong number of partition key expressions") / / get the expression value datum = ExecEvalExprSwitchContext ((ExprState *) lfirst (partexpr_item), GetPerTupleExprContext (estate), & isNull); / / switch to the next partexpr_item = lnext (partexpr_item) } values [I] = datum;// assignment isnull [I] = isNull;} if (partexpr_item! = NULL) / / Parameter setting is incorrect? Elog (ERROR, "wrong number of partition key expressions");} / * * slot_getattr-fetch one attribute of the slot's contents. * slot_getattr-extract an attribute value from slot * / static inline Datumslot_getattr (TupleTableSlot * slot, int attnum, bool * isnull) {AssertArg (attnum > 0); if (attnum > slot- > tts_nvalid) slot_getsomeattrs (slot, attnum); * isnull = slot- > tts_ isnull [attnum-1]; return slot- > tts_ values [attnum-1] } / * * This function forces the entries of the slot's Datum/isnull arrays to be * valid at least up through the attnum'th entry. * this function forces the entry of slot's Datum/isnull array to be valid at least on the first entry of attnum. * / static inline voidslot_getsomeattrs (TupleTableSlot * slot, int attnum) {if (slot- > tts_nvalid)

< attnum) slot_getsomeattrs_int(slot, attnum);}/* * slot_getsomeattrs_int - workhorse for slot_getsomeattrs() * slot_getsomeattrs_int - slot_getsomeattrs()函数的实际实现 */voidslot_getsomeattrs_int(TupleTableSlot *slot, int attnum){ /* Check for caller errors */ //检查调用者输入参数是否有误 Assert(slot->

Tts_nvalid

< attnum); /* slot_getsomeattr checked */ Assert(attnum >

0); / / attnum parameter judgment if (unlikely (attnum > slot- > tts_tupleDescriptor- > natts)) elog (ERROR, "invalid attribute number% d", attnum); / * Fetch as many attributes as possible from the underlying tuple. * / / get as many attributes as possible from the tuple. Slot- > tts_ops- > getsomeattrs (slot, attnum); / * If the underlying tuple doesn't have enough attributes, tuple descriptor * must have the missing attributes. * if the underlying tuple does not have enough attributes, then the tuple descriptor must have missing attributes. * / if (unlikely (slot- > tts_nvalid)

< attnum)) { slot_getmissingattrs(slot, slot->

Tts_nvalid, attnum); slot- > tts_nvalid = attnum;}} 3. Tracking analysis

The test script is as follows

-- Hash Partitiondrop table if exists tincture hashworthy partitionalist create table t_hash_partition (C1 int not null,c2 varchar (40), c3 varchar (40)) partition by hash (C1); create table t_hash_partition_1 partition of t_hash_partition for values with (modulus 6); create table t_hash_partition_2 partition of t_hash_partition for values with (modulus 6); create table t_hash_partition_3 partition of t_hash_partition for values with (modulus 6) Create table t_hash_partition_4 partition of t_hash_partition for values with (modulus 6); create table t_hash_partition_5 partition of t_hash_partition for values with (modulus 6); create table t_hash_partition_6 partition of t_hash_partition for values with (modulus 6); insert into t_hash_partition (c1, c2, and c3) VALUES (20, HASH0, HASH0')

Start gdb and set breakpoint

(gdb) b FormPartitionKeyDatumBreakpoint 5 at 0x6e30d2: file execPartition.c, line 1087. (gdb) b slot_getattrBreakpoint 6 at 0x489d9b: file heaptuple.c, line 1510. (gdb) cContinuing.Breakpoint 5, FormPartitionKeyDatum (pd=0x2e1bfa0, slot=0x2e1b8a0, estate=0x2e1aeb8, values=0x7fff4e2407a0, isnull=0x7fff4e240780) at execPartition.c:10871087 if (pd- > key- > partexprs! = NIL & & pd- > keystate = NIL)

Loop to get the corresponding key value according to the partition key

1087 if (pd- > key- > partexprs! = NIL & & pd- > keystate = = NIL) (gdb) n1097 partexpr_item = list_head (pd- > keystate); (gdb) 1098 for (I = 0; I

< pd->

Key- > partnatts; iTunes +) (gdb) 1100 AttrNumber keycol = pd- > key- > partattrs [I]; (gdb) 1104 if (keycol! = 0) (gdb) 1107 datum = slot_getattr (slot, keycol, & isNull)

Enter the function slot_getattr

(gdb) stepBreakpoint 6, slot_getattr (slot=0x2e1b8a0, attnum=1, isnull=0x7fff4e240735) at heaptuple.c:15101510 HeapTuple tuple = slot- > tts_tuple

Get the result. The partition key value is 20.

(gdb) p * isnull$31 = false (gdb) p slot- > tts_ values [attnum-1] $32 = 20

Return to the FormPartitionKeyDatum function

(gdb) n1593} (gdb) FormPartitionKeyDatum (pd=0x2e1bfa0, slot=0x2e1b8a0, estate=0x2e1aeb8, values=0x7fff4e2407a0, isnull=0x7fff4e240780) at execPartition.c:11191119 values [I] = datum

Complete the call

1119 values [I] = datum; (gdb) n1120 isnull [I] = isNull; (gdb) 1098 for (I = 0; I

< pd->

Key- > partnatts; iTunes +) (gdb) 1123 if (partexpr_item! = NULL) (gdb) 1125} (gdb) ExecFindPartition (resultRelInfo=0x2e1b108, pd=0x2e1c5b8, slot=0x2e1b8a0, estate=0x2e1aeb8) at execPartition.c:282282 if (partdesc- > nparts = = 0) so far, the study on "what is the partition key function of Tuple in PostgreSQL" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report