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

Commit6afa610

Browse files
committed
attempt to fix performance issues described in issue#164
1 parent79e11d9 commit6afa610

File tree

4 files changed

+153
-81
lines changed

4 files changed

+153
-81
lines changed

‎expected/pathman_rebuild_updates.out

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,10 @@ UPDATE test_updates.test SET b = 0 WHERE val = 1 RETURNING *, tableoid::REGCLASS
4343
EXPLAIN (COSTS OFF) UPDATE test_updates.test SET b = 0 WHERE val = 101;
4444
QUERY PLAN
4545
-----------------------------
46-
Update on test
47-
Update on test
48-
Update on test_11
49-
-> Seq Scan on test
50-
Filter: (val = 101)
46+
Update on test_11
5147
-> Seq Scan on test_11
5248
Filter: (val = 101)
53-
(7 rows)
49+
(3 rows)
5450

5551
UPDATE test_updates.test SET b = 0 WHERE val = 101 RETURNING *, tableoid::REGCLASS;
5652
val | b | tableoid

‎src/include/compat/pg_compat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include"nodes/pg_list.h"
3030
#include"optimizer/cost.h"
3131
#include"optimizer/paths.h"
32+
#include"optimizer/prep.h"
3233
#include"utils/memutils.h"
3334

3435
/*

‎src/pg_pathman.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include"miscadmin.h"
2727
#include"optimizer/clauses.h"
2828
#include"optimizer/plancat.h"
29-
#include"optimizer/prep.h"
3029
#include"optimizer/restrictinfo.h"
3130
#include"optimizer/cost.h"
3231
#include"utils/datum.h"

‎src/planner_tree_modification.c

Lines changed: 150 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ typedef struct
9494
}transform_query_cxt;
9595

9696

97+
typedefstruct
98+
{
99+
Indexchild_varno;
100+
List*translated_vars;
101+
}adjust_appendrel_varnos_cxt;
102+
103+
97104

98105
staticboolpathman_transform_query_walker(Node*node,void*context);
99106

@@ -103,6 +110,7 @@ static void handle_modification_query(Query *parse, transform_query_cxt *context
103110
staticvoidpartition_filter_visitor(Plan*plan,void*context);
104111

105112
staticNode*eval_extern_params_mutator(Node*node,ParamListInfoparams);
113+
staticbooladjust_appendrel_varnos(Node*node,adjust_appendrel_varnos_cxt*context);
106114

107115

108116
/*
@@ -366,20 +374,20 @@ handle_modification_query(Query *parse, transform_query_cxt *context)
366374
WrapperNode*wrap;
367375
Expr*expr;
368376
WalkerContextwcxt;
369-
Indexresult_rel;
377+
Indexresult_rti;
370378
intnum_selected;
371379
ParamListInfoparams;
372380

373381
/* Fetch index of result relation */
374-
result_rel=parse->resultRelation;
382+
result_rti=parse->resultRelation;
375383

376384
/* Exit if it's not a DELETE or UPDATE query */
377-
if (result_rel==0||
385+
if (result_rti==0||
378386
(parse->commandType!=CMD_UPDATE&&
379387
parse->commandType!=CMD_DELETE))
380388
return;
381389

382-
rte=rt_fetch(result_rel,parse->rtable);
390+
rte=rt_fetch(result_rti,parse->rtable);
383391

384392
/* Exit if it's DELETE FROM ONLY table */
385393
if (!rte->inh)return;
@@ -406,7 +414,7 @@ handle_modification_query(Query *parse, transform_query_cxt *context)
406414
expr= (Expr*)eval_extern_params_mutator((Node*)expr,params);
407415

408416
/* Prepare partitioning expression */
409-
prel_expr=PrelExpressionForRelid(prel,result_rel);
417+
prel_expr=PrelExpressionForRelid(prel,result_rti);
410418

411419
/* Parse syntax tree and extract partition ranges */
412420
InitWalkerContext(&wcxt,prel_expr,prel,NULL);
@@ -430,13 +438,14 @@ handle_modification_query(Query *parse, transform_query_cxt *context)
430438
Relationchild_rel,
431439
parent_rel;
432440

433-
void*tuple_map;/* we don't need the map itself */
434-
435441
LOCKMODElockmode=RowExclusiveLock;/* UPDATE | DELETE */
436442

437443
HeapTuplesyscache_htup;
438444
charchild_relkind;
439445

446+
List*translated_vars;
447+
adjust_appendrel_varnos_cxtaav_cxt;
448+
440449
/* Lock 'child' table */
441450
LockRelationOid(child,lockmode);
442451

@@ -460,19 +469,23 @@ handle_modification_query(Query *parse, transform_query_cxt *context)
460469
child_rel=heap_open(child,NoLock);
461470
parent_rel=heap_open(parent,NoLock);
462471

463-
/* Build a conversion map (may be trivial, i.e. NULL) */
464-
tuple_map=build_part_tuple_map(parent_rel,child_rel);
465-
if (tuple_map)
466-
free_conversion_map((TupleConversionMap*)tuple_map);
472+
make_inh_translation_list(parent_rel,child_rel,0,&translated_vars);
473+
474+
/* Translate varnos for this child */
475+
aav_cxt.child_varno=result_rti;
476+
aav_cxt.translated_vars=translated_vars;
477+
if (adjust_appendrel_varnos((Node*)parse,&aav_cxt))
478+
return;/* failed to perform rewrites */
479+
480+
/* Translate column privileges for this child */
481+
rte->selectedCols=translate_col_privs(rte->selectedCols,translated_vars);
482+
rte->insertedCols=translate_col_privs(rte->insertedCols,translated_vars);
483+
rte->updatedCols=translate_col_privs(rte->updatedCols,translated_vars);
467484

468485
/* Close relations (should remain locked, though) */
469486
heap_close(child_rel,NoLock);
470487
heap_close(parent_rel,NoLock);
471488

472-
/* Exit if tuple map was NOT trivial */
473-
if (tuple_map)/* just checking the pointer! */
474-
return;
475-
476489
/* Update RTE's relid and relkind (for FDW) */
477490
rte->relid=child;
478491
rte->relkind=child_relkind;
@@ -490,6 +503,128 @@ handle_modification_query(Query *parse, transform_query_cxt *context)
490503
}
491504
}
492505

506+
/* Replace extern param nodes with consts */
507+
staticNode*
508+
eval_extern_params_mutator(Node*node,ParamListInfoparams)
509+
{
510+
if (node==NULL)
511+
returnNULL;
512+
513+
if (IsA(node,Param))
514+
{
515+
Param*param= (Param*)node;
516+
517+
Assert(params);
518+
519+
/* Look to see if we've been given a value for this Param */
520+
if (param->paramkind==PARAM_EXTERN&&
521+
param->paramid>0&&
522+
param->paramid <=params->numParams)
523+
{
524+
ParamExternData*prm=&params->params[param->paramid-1];
525+
526+
if (OidIsValid(prm->ptype))
527+
{
528+
/* OK to substitute parameter value? */
529+
if (prm->pflags&PARAM_FLAG_CONST)
530+
{
531+
/*
532+
* Return a Const representing the param value.
533+
* Must copy pass-by-ref datatypes, since the
534+
* Param might be in a memory context
535+
* shorter-lived than our output plan should be.
536+
*/
537+
int16typLen;
538+
booltypByVal;
539+
Datumpval;
540+
541+
Assert(prm->ptype==param->paramtype);
542+
get_typlenbyval(param->paramtype,
543+
&typLen,&typByVal);
544+
if (prm->isnull||typByVal)
545+
pval=prm->value;
546+
else
547+
pval=datumCopy(prm->value,typByVal,typLen);
548+
return (Node*)makeConst(param->paramtype,
549+
param->paramtypmod,
550+
param->paramcollid,
551+
(int)typLen,
552+
pval,
553+
prm->isnull,
554+
typByVal);
555+
}
556+
}
557+
}
558+
}
559+
560+
returnexpression_tree_mutator(node,eval_extern_params_mutator,
561+
(void*)params);
562+
}
563+
564+
staticbool
565+
adjust_appendrel_varnos(Node*node,adjust_appendrel_varnos_cxt*context)
566+
{
567+
if (node==NULL)
568+
return false;
569+
570+
if (IsA(node,Query))
571+
{
572+
Query*query= (Query*)node;
573+
ListCell*lc;
574+
575+
foreach (lc,query->targetList)
576+
{
577+
TargetEntry*te= (TargetEntry*)lfirst(lc);
578+
Var*child_var;
579+
580+
if (te->resjunk)
581+
continue;
582+
583+
if (te->resno>list_length(context->translated_vars))
584+
return true;
585+
586+
child_var=list_nth(context->translated_vars,te->resno-1);
587+
if (!child_var)
588+
return true;
589+
590+
/* Transform attribute number */
591+
te->resno=child_var->varattno;
592+
}
593+
594+
returnquery_tree_walker((Query*)node,
595+
adjust_appendrel_varnos,
596+
context,
597+
QTW_IGNORE_RC_SUBQUERIES);
598+
}
599+
600+
if (IsA(node,Var))
601+
{
602+
Var*var= (Var*)node;
603+
604+
/* Don't tranform system columns & other relations' Vars */
605+
if (var->varoattno>0&&var->varno==context->child_varno)
606+
{
607+
Var*child_var;
608+
609+
if (var->varattno>list_length(context->translated_vars))
610+
return true;
611+
612+
child_var=list_nth(context->translated_vars,var->varattno-1);
613+
if (!child_var)
614+
return true;
615+
616+
/* Transform attribute number */
617+
var->varattno=child_var->varattno;
618+
}
619+
620+
return false;
621+
}
622+
623+
returnexpression_tree_walker(node,
624+
adjust_appendrel_varnos,
625+
context);
626+
}
627+
493628

494629
/*
495630
* -------------------------------
@@ -592,65 +727,6 @@ get_rel_parenthood_status(RangeTblEntry *rte)
592727
}
593728

594729

595-
/* Replace extern param nodes with consts */
596-
staticNode*
597-
eval_extern_params_mutator(Node*node,ParamListInfoparams)
598-
{
599-
if (node==NULL)
600-
returnNULL;
601-
602-
if (IsA(node,Param))
603-
{
604-
Param*param= (Param*)node;
605-
606-
Assert(params);
607-
608-
/* Look to see if we've been given a value for this Param */
609-
if (param->paramkind==PARAM_EXTERN&&
610-
param->paramid>0&&
611-
param->paramid <=params->numParams)
612-
{
613-
ParamExternData*prm=&params->params[param->paramid-1];
614-
615-
if (OidIsValid(prm->ptype))
616-
{
617-
/* OK to substitute parameter value? */
618-
if (prm->pflags&PARAM_FLAG_CONST)
619-
{
620-
/*
621-
* Return a Const representing the param value.
622-
* Must copy pass-by-ref datatypes, since the
623-
* Param might be in a memory context
624-
* shorter-lived than our output plan should be.
625-
*/
626-
int16typLen;
627-
booltypByVal;
628-
Datumpval;
629-
630-
Assert(prm->ptype==param->paramtype);
631-
get_typlenbyval(param->paramtype,
632-
&typLen,&typByVal);
633-
if (prm->isnull||typByVal)
634-
pval=prm->value;
635-
else
636-
pval=datumCopy(prm->value,typByVal,typLen);
637-
return (Node*)makeConst(param->paramtype,
638-
param->paramtypmod,
639-
param->paramcollid,
640-
(int)typLen,
641-
pval,
642-
prm->isnull,
643-
typByVal);
644-
}
645-
}
646-
}
647-
}
648-
649-
returnexpression_tree_mutator(node,eval_extern_params_mutator,
650-
(void*)params);
651-
}
652-
653-
654730
/*
655731
* -----------------------------------------------
656732
* Count number of times we've visited planner()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp