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

Commita018546

Browse files
committed
Rearrange the implementation of index-only scans.
This commit changes index-only scans so that data is read directly from theindex tuple without first generating a faux heap tuple. The only immediatebenefit is that indexes on system columns (such as OID) can be used inindex-only scans, but this is necessary infrastructure if we are ever tosupport index-only scans on expression indexes. The executor is now readyfor that, though the planner still needs substantial work to recognizethe possibility.To do this, Vars in index-only plan nodes have to refer to index columnsnot heap columns. I introduced a new special varno, INDEX_VAR, to marksuch Vars to avoid confusion. (In passing, this commit renames the twoexisting special varnos to OUTER_VAR and INNER_VAR.) This allowsruleutils.c to handle them with logic similar to what we use for subplanreference Vars.Since index-only scans are now fundamentally different from regularindexscans so far as their expression subtrees are concerned, I also choseto change them to have their own plan node type (and hence, their ownexecutor source file).
1 parentfa351d5 commita018546

34 files changed

+1313
-420
lines changed

‎src/backend/commands/explain.c

Lines changed: 79 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ static void show_instrumentation_count(const char *qlabel, int which,
7979
PlanState*planstate,ExplainState*es);
8080
staticvoidshow_foreignscan_info(ForeignScanState*fsstate,ExplainState*es);
8181
staticconstchar*explain_get_index_name(OidindexId);
82+
staticvoidExplainIndexScanDetails(Oidindexid,ScanDirectionindexorderdir,
83+
ExplainState*es);
8284
staticvoidExplainScanTarget(Scan*plan,ExplainState*es);
8385
staticvoidExplainModifyTarget(ModifyTable*plan,ExplainState*es);
8486
staticvoidExplainTargetRel(Plan*plan,Indexrti,ExplainState*es);
@@ -656,10 +658,10 @@ ExplainNode(PlanState *planstate, List *ancestors,
656658
pname=sname="Seq Scan";
657659
break;
658660
caseT_IndexScan:
659-
if (((IndexScan*)plan)->indexonly)
660-
pname=sname="Index Only Scan";
661-
else
662-
pname=sname="Index Scan";
661+
pname=sname="Index Scan";
662+
break;
663+
caseT_IndexOnlyScan:
664+
pname=sname="Index Only Scan";
663665
break;
664666
caseT_BitmapIndexScan:
665667
pname=sname="Bitmap Index Scan";
@@ -793,42 +795,6 @@ ExplainNode(PlanState *planstate, List *ancestors,
793795

794796
switch (nodeTag(plan))
795797
{
796-
caseT_IndexScan:
797-
{
798-
IndexScan*indexscan= (IndexScan*)plan;
799-
constchar*indexname=
800-
explain_get_index_name(indexscan->indexid);
801-
802-
if (es->format==EXPLAIN_FORMAT_TEXT)
803-
{
804-
if (ScanDirectionIsBackward(indexscan->indexorderdir))
805-
appendStringInfoString(es->str," Backward");
806-
appendStringInfo(es->str," using %s",indexname);
807-
}
808-
else
809-
{
810-
constchar*scandir;
811-
812-
switch (indexscan->indexorderdir)
813-
{
814-
caseBackwardScanDirection:
815-
scandir="Backward";
816-
break;
817-
caseNoMovementScanDirection:
818-
scandir="NoMovement";
819-
break;
820-
caseForwardScanDirection:
821-
scandir="Forward";
822-
break;
823-
default:
824-
scandir="???";
825-
break;
826-
}
827-
ExplainPropertyText("Scan Direction",scandir,es);
828-
ExplainPropertyText("Index Name",indexname,es);
829-
}
830-
}
831-
/* FALL THRU */
832798
caseT_SeqScan:
833799
caseT_BitmapHeapScan:
834800
caseT_TidScan:
@@ -840,6 +806,26 @@ ExplainNode(PlanState *planstate, List *ancestors,
840806
caseT_ForeignScan:
841807
ExplainScanTarget((Scan*)plan,es);
842808
break;
809+
caseT_IndexScan:
810+
{
811+
IndexScan*indexscan= (IndexScan*)plan;
812+
813+
ExplainIndexScanDetails(indexscan->indexid,
814+
indexscan->indexorderdir,
815+
es);
816+
ExplainScanTarget((Scan*)indexscan,es);
817+
}
818+
break;
819+
caseT_IndexOnlyScan:
820+
{
821+
IndexOnlyScan*indexonlyscan= (IndexOnlyScan*)plan;
822+
823+
ExplainIndexScanDetails(indexonlyscan->indexid,
824+
indexonlyscan->indexorderdir,
825+
es);
826+
ExplainScanTarget((Scan*)indexonlyscan,es);
827+
}
828+
break;
843829
caseT_BitmapIndexScan:
844830
{
845831
BitmapIndexScan*bitmapindexscan= (BitmapIndexScan*)plan;
@@ -1014,6 +1000,19 @@ ExplainNode(PlanState *planstate, List *ancestors,
10141000
show_instrumentation_count("Rows Removed by Filter",1,
10151001
planstate,es);
10161002
break;
1003+
caseT_IndexOnlyScan:
1004+
show_scan_qual(((IndexOnlyScan*)plan)->indexqual,
1005+
"Index Cond",planstate,ancestors,es);
1006+
if (((IndexOnlyScan*)plan)->indexqual)
1007+
show_instrumentation_count("Rows Removed by Index Recheck",2,
1008+
planstate,es);
1009+
show_scan_qual(((IndexOnlyScan*)plan)->indexorderby,
1010+
"Order By",planstate,ancestors,es);
1011+
show_scan_qual(plan->qual,"Filter",planstate,ancestors,es);
1012+
if (plan->qual)
1013+
show_instrumentation_count("Rows Removed by Filter",1,
1014+
planstate,es);
1015+
break;
10171016
caseT_BitmapIndexScan:
10181017
show_scan_qual(((BitmapIndexScan*)plan)->indexqualorig,
10191018
"Index Cond",planstate,ancestors,es);
@@ -1626,6 +1625,45 @@ explain_get_index_name(Oid indexId)
16261625
returnresult;
16271626
}
16281627

1628+
/*
1629+
* Add some additional details about an IndexScan or IndexOnlyScan
1630+
*/
1631+
staticvoid
1632+
ExplainIndexScanDetails(Oidindexid,ScanDirectionindexorderdir,
1633+
ExplainState*es)
1634+
{
1635+
constchar*indexname=explain_get_index_name(indexid);
1636+
1637+
if (es->format==EXPLAIN_FORMAT_TEXT)
1638+
{
1639+
if (ScanDirectionIsBackward(indexorderdir))
1640+
appendStringInfoString(es->str," Backward");
1641+
appendStringInfo(es->str," using %s",indexname);
1642+
}
1643+
else
1644+
{
1645+
constchar*scandir;
1646+
1647+
switch (indexorderdir)
1648+
{
1649+
caseBackwardScanDirection:
1650+
scandir="Backward";
1651+
break;
1652+
caseNoMovementScanDirection:
1653+
scandir="NoMovement";
1654+
break;
1655+
caseForwardScanDirection:
1656+
scandir="Forward";
1657+
break;
1658+
default:
1659+
scandir="???";
1660+
break;
1661+
}
1662+
ExplainPropertyText("Scan Direction",scandir,es);
1663+
ExplainPropertyText("Index Name",indexname,es);
1664+
}
1665+
}
1666+
16291667
/*
16301668
* Show the target of a Scan node
16311669
*/
@@ -1670,6 +1708,7 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
16701708
{
16711709
caseT_SeqScan:
16721710
caseT_IndexScan:
1711+
caseT_IndexOnlyScan:
16731712
caseT_BitmapHeapScan:
16741713
caseT_TidScan:
16751714
caseT_ForeignScan:

‎src/backend/commands/trigger.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,9 +2734,9 @@ TriggerEnabled(EState *estate, ResultRelInfo *relinfo,
27342734

27352735
oldContext=MemoryContextSwitchTo(estate->es_query_cxt);
27362736
tgqual=stringToNode(trigger->tgqual);
2737-
/* Change references to OLD and NEW toINNER andOUTER */
2738-
ChangeVarNodes(tgqual,PRS2_OLD_VARNO,INNER,0);
2739-
ChangeVarNodes(tgqual,PRS2_NEW_VARNO,OUTER,0);
2737+
/* Change references to OLD and NEW toINNER_VAR andOUTER_VAR */
2738+
ChangeVarNodes(tgqual,PRS2_OLD_VARNO,INNER_VAR,0);
2739+
ChangeVarNodes(tgqual,PRS2_NEW_VARNO,OUTER_VAR,0);
27402740
/* ExecQual wants implicit-AND form */
27412741
tgqual= (Node*)make_ands_implicit((Expr*)tgqual);
27422742
*predicate= (List*)ExecPrepareExpr((Expr*)tgqual,estate);
@@ -2783,7 +2783,7 @@ TriggerEnabled(EState *estate, ResultRelInfo *relinfo,
27832783

27842784
/*
27852785
* Finally evaluate the expression, making the old and/or new tuples
2786-
* available asINNER/OUTER respectively.
2786+
* available asINNER_VAR/OUTER_VAR respectively.
27872787
*/
27882788
econtext->ecxt_innertuple=oldslot;
27892789
econtext->ecxt_outertuple=newslot;

‎src/backend/executor/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ OBJS = execAmi.o execCurrent.o execGrouping.o execJunk.o execMain.o \
1717
execUtils.o functions.o instrument.o nodeAppend.o nodeAgg.o\
1818
nodeBitmapAnd.o nodeBitmapOr.o\
1919
nodeBitmapHeapscan.o nodeBitmapIndexscan.o nodeHash.o\
20-
nodeHashjoin.o nodeIndexscan.o nodeLimit.o nodeLockRows.o\
20+
nodeHashjoin.o nodeIndexscan.o nodeIndexonlyscan.o\
21+
nodeLimit.o nodeLockRows.o\
2122
nodeMaterial.o nodeMergeAppend.o nodeMergejoin.o nodeModifyTable.o\
2223
nodeNestloop.o nodeFunctionscan.o nodeRecursiveunion.o nodeResult.o\
2324
nodeSeqscan.o nodeSetOp.o nodeSort.o nodeUnique.o\

‎src/backend/executor/execAmi.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include"executor/nodeGroup.h"
2727
#include"executor/nodeHash.h"
2828
#include"executor/nodeHashjoin.h"
29+
#include"executor/nodeIndexonlyscan.h"
2930
#include"executor/nodeIndexscan.h"
3031
#include"executor/nodeLimit.h"
3132
#include"executor/nodeLockRows.h"
@@ -155,6 +156,10 @@ ExecReScan(PlanState *node)
155156
ExecReScanIndexScan((IndexScanState*)node);
156157
break;
157158

159+
caseT_IndexOnlyScanState:
160+
ExecReScanIndexOnlyScan((IndexOnlyScanState*)node);
161+
break;
162+
158163
caseT_BitmapIndexScanState:
159164
ExecReScanBitmapIndexScan((BitmapIndexScanState*)node);
160165
break;
@@ -273,6 +278,10 @@ ExecMarkPos(PlanState *node)
273278
ExecIndexMarkPos((IndexScanState*)node);
274279
break;
275280

281+
caseT_IndexOnlyScanState:
282+
ExecIndexOnlyMarkPos((IndexOnlyScanState*)node);
283+
break;
284+
276285
caseT_TidScanState:
277286
ExecTidMarkPos((TidScanState*)node);
278287
break;
@@ -326,6 +335,10 @@ ExecRestrPos(PlanState *node)
326335
ExecIndexRestrPos((IndexScanState*)node);
327336
break;
328337

338+
caseT_IndexOnlyScanState:
339+
ExecIndexOnlyRestrPos((IndexOnlyScanState*)node);
340+
break;
341+
329342
caseT_TidScanState:
330343
ExecTidRestrPos((TidScanState*)node);
331344
break;
@@ -371,6 +384,7 @@ ExecSupportsMarkRestore(NodeTag plantype)
371384
{
372385
caseT_SeqScan:
373386
caseT_IndexScan:
387+
caseT_IndexOnlyScan:
374388
caseT_TidScan:
375389
caseT_ValuesScan:
376390
caseT_Material:
@@ -442,6 +456,10 @@ ExecSupportsBackwardScan(Plan *node)
442456
returnIndexSupportsBackwardScan(((IndexScan*)node)->indexid)&&
443457
TargetListSupportsBackwardScan(node->targetlist);
444458

459+
caseT_IndexOnlyScan:
460+
returnIndexSupportsBackwardScan(((IndexOnlyScan*)node)->indexid)&&
461+
TargetListSupportsBackwardScan(node->targetlist);
462+
445463
caseT_SubqueryScan:
446464
returnExecSupportsBackwardScan(((SubqueryScan*)node)->subplan)&&
447465
TargetListSupportsBackwardScan(node->targetlist);
@@ -474,7 +492,8 @@ TargetListSupportsBackwardScan(List *targetlist)
474492
}
475493

476494
/*
477-
* An IndexScan node supports backward scan only if the index's AM does.
495+
* An IndexScan or IndexOnlyScan node supports backward scan only if the
496+
* index's AM does.
478497
*/
479498
staticbool
480499
IndexSupportsBackwardScan(Oidindexid)

‎src/backend/executor/execCurrent.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ search_plan_tree(PlanState *node, Oid table_oid)
262262
*/
263263
caseT_SeqScanState:
264264
caseT_IndexScanState:
265+
caseT_IndexOnlyScanState:
265266
caseT_BitmapHeapScanState:
266267
caseT_TidScanState:
267268
{

‎src/backend/executor/execProcnode.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#include"executor/nodeGroup.h"
9090
#include"executor/nodeHash.h"
9191
#include"executor/nodeHashjoin.h"
92+
#include"executor/nodeIndexonlyscan.h"
9293
#include"executor/nodeIndexscan.h"
9394
#include"executor/nodeLimit.h"
9495
#include"executor/nodeLockRows.h"
@@ -192,6 +193,11 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
192193
estate,eflags);
193194
break;
194195

196+
caseT_IndexOnlyScan:
197+
result= (PlanState*)ExecInitIndexOnlyScan((IndexOnlyScan*)node,
198+
estate,eflags);
199+
break;
200+
195201
caseT_BitmapIndexScan:
196202
result= (PlanState*)ExecInitBitmapIndexScan((BitmapIndexScan*)node,
197203
estate,eflags);
@@ -397,6 +403,10 @@ ExecProcNode(PlanState *node)
397403
result=ExecIndexScan((IndexScanState*)node);
398404
break;
399405

406+
caseT_IndexOnlyScanState:
407+
result=ExecIndexOnlyScan((IndexOnlyScanState*)node);
408+
break;
409+
400410
/* BitmapIndexScanState does not yield tuples */
401411

402412
caseT_BitmapHeapScanState:
@@ -627,6 +637,10 @@ ExecEndNode(PlanState *node)
627637
ExecEndIndexScan((IndexScanState*)node);
628638
break;
629639

640+
caseT_IndexOnlyScanState:
641+
ExecEndIndexOnlyScan((IndexOnlyScanState*)node);
642+
break;
643+
630644
caseT_BitmapIndexScanState:
631645
ExecEndBitmapIndexScan((BitmapIndexScanState*)node);
632646
break;

‎src/backend/executor/execQual.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -578,14 +578,16 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
578578
/* Get the input slot and attribute number we want */
579579
switch (variable->varno)
580580
{
581-
caseINNER:/* get the tuple from the inner node */
581+
caseINNER_VAR:/* get the tuple from the inner node */
582582
slot=econtext->ecxt_innertuple;
583583
break;
584584

585-
caseOUTER:/* get the tuple from the outer node */
585+
caseOUTER_VAR:/* get the tuple from the outer node */
586586
slot=econtext->ecxt_outertuple;
587587
break;
588588

589+
/* INDEX_VAR is handled by default case */
590+
589591
default:/* get the tuple from the relation being
590592
* scanned */
591593
slot=econtext->ecxt_scantuple;
@@ -761,14 +763,16 @@ ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
761763
/* Get the input slot and attribute number we want */
762764
switch (variable->varno)
763765
{
764-
caseINNER:/* get the tuple from the inner node */
766+
caseINNER_VAR:/* get the tuple from the inner node */
765767
slot=econtext->ecxt_innertuple;
766768
break;
767769

768-
caseOUTER:/* get the tuple from the outer node */
770+
caseOUTER_VAR:/* get the tuple from the outer node */
769771
slot=econtext->ecxt_outertuple;
770772
break;
771773

774+
/* INDEX_VAR is handled by default case */
775+
772776
default:/* get the tuple from the relation being
773777
* scanned */
774778
slot=econtext->ecxt_scantuple;
@@ -804,14 +808,16 @@ ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
804808
/* Get the input slot we want */
805809
switch (variable->varno)
806810
{
807-
caseINNER:/* get the tuple from the inner node */
811+
caseINNER_VAR:/* get the tuple from the inner node */
808812
slot=econtext->ecxt_innertuple;
809813
break;
810814

811-
caseOUTER:/* get the tuple from the outer node */
815+
caseOUTER_VAR:/* get the tuple from the outer node */
812816
slot=econtext->ecxt_outertuple;
813817
break;
814818

819+
/* INDEX_VAR is handled by default case */
820+
815821
default:/* get the tuple from the relation being
816822
* scanned */
817823
slot=econtext->ecxt_scantuple;
@@ -873,14 +879,16 @@ ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
873879
/* Get the input slot we want */
874880
switch (variable->varno)
875881
{
876-
caseINNER:/* get the tuple from the inner node */
882+
caseINNER_VAR:/* get the tuple from the inner node */
877883
slot=econtext->ecxt_innertuple;
878884
break;
879885

880-
caseOUTER:/* get the tuple from the outer node */
886+
caseOUTER_VAR:/* get the tuple from the outer node */
881887
slot=econtext->ecxt_outertuple;
882888
break;
883889

890+
/* INDEX_VAR is handled by default case */
891+
884892
default:/* get the tuple from the relation being
885893
* scanned */
886894
slot=econtext->ecxt_scantuple;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp