Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4e5fe9a

Browse files
committed
Centralize executor-related partitioning code.
Some code is moved from partition.c, which has grown very quickly lately;splitting the executor parts out might help to keep it from gettingtotally out of control. Other code is moved from execMain.c. All ismoved to a new file execPartition.c. get_partition_for_tuple now hasa new interface that more clearly separates executor concerns fromgeneric concerns.Amit Langote. A slight comment tweak by me.Discussion:http://postgr.es/m/1f0985f8-3b61-8bc4-4350-baa6d804cb6d@lab.ntt.co.jp
1 parentcd8ce3a commit4e5fe9a

File tree

9 files changed

+717
-695
lines changed

9 files changed

+717
-695
lines changed

‎src/backend/catalog/partition.c

Lines changed: 80 additions & 375 deletions
Large diffs are not rendered by default.

‎src/backend/commands/copy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include"commands/copy.h"
2828
#include"commands/defrem.h"
2929
#include"commands/trigger.h"
30+
#include"executor/execPartition.h"
3031
#include"executor/executor.h"
3132
#include"libpq/libpq.h"
3233
#include"libpq/pqformat.h"

‎src/backend/executor/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global
1414

1515
OBJS = execAmi.o execCurrent.o execExpr.o execExprInterp.o\
1616
execGrouping.o execIndexing.o execJunk.o\
17-
execMain.o execParallel.o execProcnode.o\
17+
execMain.o execParallel.oexecPartition.oexecProcnode.o\
1818
execReplication.o execScan.o execSRF.o execTuples.o\
1919
execUtils.o functions.o instrument.o nodeAppend.o nodeAgg.o\
2020
nodeBitmapAnd.o nodeBitmapOr.o\

‎src/backend/executor/execMain.c

Lines changed: 3 additions & 263 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
#include"access/xact.h"
4444
#include"catalog/namespace.h"
4545
#include"catalog/partition.h"
46-
#include"catalog/pg_inherits_fn.h"
4746
#include"catalog/pg_publication.h"
4847
#include"commands/matview.h"
4948
#include"commands/trigger.h"
@@ -98,14 +97,8 @@ static char *ExecBuildSlotValueDescription(Oid reloid,
9897
TupleDesctupdesc,
9998
Bitmapset*modifiedCols,
10099
intmaxfieldlen);
101-
staticchar*ExecBuildSlotPartitionKeyDescription(Relationrel,
102-
Datum*values,
103-
bool*isnull,
104-
intmaxfieldlen);
105100
staticvoidEvalPlanQualStart(EPQState*epqstate,EState*parentestate,
106101
Plan*planTree);
107-
staticvoidExecPartitionCheck(ResultRelInfo*resultRelInfo,
108-
TupleTableSlot*slot,EState*estate);
109102

110103
/*
111104
* Note that GetUpdatedColumns() also exists in commands/trigger.c. There does
@@ -1854,8 +1847,10 @@ ExecRelCheck(ResultRelInfo *resultRelInfo,
18541847

18551848
/*
18561849
* ExecPartitionCheck --- check that tuple meets the partition constraint.
1850+
*
1851+
* Exported in executor.h for outside use.
18571852
*/
1858-
staticvoid
1853+
void
18591854
ExecPartitionCheck(ResultRelInfo*resultRelInfo,TupleTableSlot*slot,
18601855
EState*estate)
18611856
{
@@ -3245,258 +3240,3 @@ EvalPlanQualEnd(EPQState *epqstate)
32453240
epqstate->planstate=NULL;
32463241
epqstate->origslot=NULL;
32473242
}
3248-
3249-
/*
3250-
* ExecSetupPartitionTupleRouting - set up information needed during
3251-
* tuple routing for partitioned tables
3252-
*
3253-
* Output arguments:
3254-
* 'pd' receives an array of PartitionDispatch objects with one entry for
3255-
*every partitioned table in the partition tree
3256-
* 'partitions' receives an array of ResultRelInfo* objects with one entry for
3257-
*every leaf partition in the partition tree
3258-
* 'tup_conv_maps' receives an array of TupleConversionMap objects with one
3259-
*entry for every leaf partition (required to convert input tuple based
3260-
*on the root table's rowtype to a leaf partition's rowtype after tuple
3261-
*routing is done)
3262-
* 'partition_tuple_slot' receives a standalone TupleTableSlot to be used
3263-
*to manipulate any given leaf partition's rowtype after that partition
3264-
*is chosen by tuple-routing.
3265-
* 'num_parted' receives the number of partitioned tables in the partition
3266-
*tree (= the number of entries in the 'pd' output array)
3267-
* 'num_partitions' receives the number of leaf partitions in the partition
3268-
*tree (= the number of entries in the 'partitions' and 'tup_conv_maps'
3269-
*output arrays
3270-
*
3271-
* Note that all the relations in the partition tree are locked using the
3272-
* RowExclusiveLock mode upon return from this function.
3273-
*/
3274-
void
3275-
ExecSetupPartitionTupleRouting(Relationrel,
3276-
IndexresultRTindex,
3277-
EState*estate,
3278-
PartitionDispatch**pd,
3279-
ResultRelInfo***partitions,
3280-
TupleConversionMap***tup_conv_maps,
3281-
TupleTableSlot**partition_tuple_slot,
3282-
int*num_parted,int*num_partitions)
3283-
{
3284-
TupleDesctupDesc=RelationGetDescr(rel);
3285-
List*leaf_parts;
3286-
ListCell*cell;
3287-
inti;
3288-
ResultRelInfo*leaf_part_rri;
3289-
3290-
/*
3291-
* Get the information about the partition tree after locking all the
3292-
* partitions.
3293-
*/
3294-
(void)find_all_inheritors(RelationGetRelid(rel),RowExclusiveLock,NULL);
3295-
*pd=RelationGetPartitionDispatchInfo(rel,num_parted,&leaf_parts);
3296-
*num_partitions=list_length(leaf_parts);
3297-
*partitions= (ResultRelInfo**)palloc(*num_partitions*
3298-
sizeof(ResultRelInfo*));
3299-
*tup_conv_maps= (TupleConversionMap**)palloc0(*num_partitions*
3300-
sizeof(TupleConversionMap*));
3301-
3302-
/*
3303-
* Initialize an empty slot that will be used to manipulate tuples of any
3304-
* given partition's rowtype. It is attached to the caller-specified node
3305-
* (such as ModifyTableState) and released when the node finishes
3306-
* processing.
3307-
*/
3308-
*partition_tuple_slot=MakeTupleTableSlot();
3309-
3310-
leaf_part_rri= (ResultRelInfo*)palloc0(*num_partitions*
3311-
sizeof(ResultRelInfo));
3312-
i=0;
3313-
foreach(cell,leaf_parts)
3314-
{
3315-
Relationpartrel;
3316-
TupleDescpart_tupdesc;
3317-
3318-
/*
3319-
* We locked all the partitions above including the leaf partitions.
3320-
* Note that each of the relations in *partitions are eventually
3321-
* closed by the caller.
3322-
*/
3323-
partrel=heap_open(lfirst_oid(cell),NoLock);
3324-
part_tupdesc=RelationGetDescr(partrel);
3325-
3326-
/*
3327-
* Save a tuple conversion map to convert a tuple routed to this
3328-
* partition from the parent's type to the partition's.
3329-
*/
3330-
(*tup_conv_maps)[i]=convert_tuples_by_name(tupDesc,part_tupdesc,
3331-
gettext_noop("could not convert row type"));
3332-
3333-
InitResultRelInfo(leaf_part_rri,
3334-
partrel,
3335-
resultRTindex,
3336-
rel,
3337-
estate->es_instrument);
3338-
3339-
/*
3340-
* Verify result relation is a valid target for INSERT.
3341-
*/
3342-
CheckValidResultRel(leaf_part_rri,CMD_INSERT);
3343-
3344-
/*
3345-
* Open partition indices (remember we do not support ON CONFLICT in
3346-
* case of partitioned tables, so we do not need support information
3347-
* for speculative insertion)
3348-
*/
3349-
if (leaf_part_rri->ri_RelationDesc->rd_rel->relhasindex&&
3350-
leaf_part_rri->ri_IndexRelationDescs==NULL)
3351-
ExecOpenIndices(leaf_part_rri, false);
3352-
3353-
estate->es_leaf_result_relations=
3354-
lappend(estate->es_leaf_result_relations,leaf_part_rri);
3355-
3356-
(*partitions)[i]=leaf_part_rri++;
3357-
i++;
3358-
}
3359-
}
3360-
3361-
/*
3362-
* ExecFindPartition -- Find a leaf partition in the partition tree rooted
3363-
* at parent, for the heap tuple contained in *slot
3364-
*
3365-
* estate must be non-NULL; we'll need it to compute any expressions in the
3366-
* partition key(s)
3367-
*
3368-
* If no leaf partition is found, this routine errors out with the appropriate
3369-
* error message, else it returns the leaf partition sequence number returned
3370-
* by get_partition_for_tuple() unchanged.
3371-
*/
3372-
int
3373-
ExecFindPartition(ResultRelInfo*resultRelInfo,PartitionDispatch*pd,
3374-
TupleTableSlot*slot,EState*estate)
3375-
{
3376-
intresult;
3377-
PartitionDispatchData*failed_at;
3378-
TupleTableSlot*failed_slot;
3379-
3380-
/*
3381-
* First check the root table's partition constraint, if any. No point in
3382-
* routing the tuple if it doesn't belong in the root table itself.
3383-
*/
3384-
if (resultRelInfo->ri_PartitionCheck)
3385-
ExecPartitionCheck(resultRelInfo,slot,estate);
3386-
3387-
result=get_partition_for_tuple(pd,slot,estate,
3388-
&failed_at,&failed_slot);
3389-
if (result<0)
3390-
{
3391-
Relationfailed_rel;
3392-
Datumkey_values[PARTITION_MAX_KEYS];
3393-
boolkey_isnull[PARTITION_MAX_KEYS];
3394-
char*val_desc;
3395-
ExprContext*ecxt=GetPerTupleExprContext(estate);
3396-
3397-
failed_rel=failed_at->reldesc;
3398-
ecxt->ecxt_scantuple=failed_slot;
3399-
FormPartitionKeyDatum(failed_at,failed_slot,estate,
3400-
key_values,key_isnull);
3401-
val_desc=ExecBuildSlotPartitionKeyDescription(failed_rel,
3402-
key_values,
3403-
key_isnull,
3404-
64);
3405-
Assert(OidIsValid(RelationGetRelid(failed_rel)));
3406-
ereport(ERROR,
3407-
(errcode(ERRCODE_CHECK_VIOLATION),
3408-
errmsg("no partition of relation \"%s\" found for row",
3409-
RelationGetRelationName(failed_rel)),
3410-
val_desc ?errdetail("Partition key of the failing row contains %s.",val_desc) :0));
3411-
}
3412-
3413-
returnresult;
3414-
}
3415-
3416-
/*
3417-
* BuildSlotPartitionKeyDescription
3418-
*
3419-
* This works very much like BuildIndexValueDescription() and is currently
3420-
* used for building error messages when ExecFindPartition() fails to find
3421-
* partition for a row.
3422-
*/
3423-
staticchar*
3424-
ExecBuildSlotPartitionKeyDescription(Relationrel,
3425-
Datum*values,
3426-
bool*isnull,
3427-
intmaxfieldlen)
3428-
{
3429-
StringInfoDatabuf;
3430-
PartitionKeykey=RelationGetPartitionKey(rel);
3431-
intpartnatts=get_partition_natts(key);
3432-
inti;
3433-
Oidrelid=RelationGetRelid(rel);
3434-
AclResultaclresult;
3435-
3436-
if (check_enable_rls(relid,InvalidOid, true)==RLS_ENABLED)
3437-
returnNULL;
3438-
3439-
/* If the user has table-level access, just go build the description. */
3440-
aclresult=pg_class_aclcheck(relid,GetUserId(),ACL_SELECT);
3441-
if (aclresult!=ACLCHECK_OK)
3442-
{
3443-
/*
3444-
* Step through the columns of the partition key and make sure the
3445-
* user has SELECT rights on all of them.
3446-
*/
3447-
for (i=0;i<partnatts;i++)
3448-
{
3449-
AttrNumberattnum=get_partition_col_attnum(key,i);
3450-
3451-
/*
3452-
* If this partition key column is an expression, we return no
3453-
* detail rather than try to figure out what column(s) the
3454-
* expression includes and if the user has SELECT rights on them.
3455-
*/
3456-
if (attnum==InvalidAttrNumber||
3457-
pg_attribute_aclcheck(relid,attnum,GetUserId(),
3458-
ACL_SELECT)!=ACLCHECK_OK)
3459-
returnNULL;
3460-
}
3461-
}
3462-
3463-
initStringInfo(&buf);
3464-
appendStringInfo(&buf,"(%s) = (",
3465-
pg_get_partkeydef_columns(relid, true));
3466-
3467-
for (i=0;i<partnatts;i++)
3468-
{
3469-
char*val;
3470-
intvallen;
3471-
3472-
if (isnull[i])
3473-
val="null";
3474-
else
3475-
{
3476-
Oidfoutoid;
3477-
booltypisvarlena;
3478-
3479-
getTypeOutputInfo(get_partition_col_typid(key,i),
3480-
&foutoid,&typisvarlena);
3481-
val=OidOutputFunctionCall(foutoid,values[i]);
3482-
}
3483-
3484-
if (i>0)
3485-
appendStringInfoString(&buf,", ");
3486-
3487-
/* truncate if needed */
3488-
vallen=strlen(val);
3489-
if (vallen <=maxfieldlen)
3490-
appendStringInfoString(&buf,val);
3491-
else
3492-
{
3493-
vallen=pg_mbcliplen(val,vallen,maxfieldlen);
3494-
appendBinaryStringInfo(&buf,val,vallen);
3495-
appendStringInfoString(&buf,"...");
3496-
}
3497-
}
3498-
3499-
appendStringInfoChar(&buf,')');
3500-
3501-
returnbuf.data;
3502-
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp