Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "postgres.h"
00014
00015 #include "access/htup_details.h"
00016 #include "executor/execdebug.h"
00017 #include "executor/nodeAgg.h"
00018 #include "executor/nodeAppend.h"
00019 #include "executor/nodeBitmapAnd.h"
00020 #include "executor/nodeBitmapHeapscan.h"
00021 #include "executor/nodeBitmapIndexscan.h"
00022 #include "executor/nodeBitmapOr.h"
00023 #include "executor/nodeCtescan.h"
00024 #include "executor/nodeForeignscan.h"
00025 #include "executor/nodeFunctionscan.h"
00026 #include "executor/nodeGroup.h"
00027 #include "executor/nodeGroup.h"
00028 #include "executor/nodeHash.h"
00029 #include "executor/nodeHashjoin.h"
00030 #include "executor/nodeIndexonlyscan.h"
00031 #include "executor/nodeIndexscan.h"
00032 #include "executor/nodeLimit.h"
00033 #include "executor/nodeLockRows.h"
00034 #include "executor/nodeMaterial.h"
00035 #include "executor/nodeMergeAppend.h"
00036 #include "executor/nodeMergejoin.h"
00037 #include "executor/nodeModifyTable.h"
00038 #include "executor/nodeNestloop.h"
00039 #include "executor/nodeRecursiveunion.h"
00040 #include "executor/nodeResult.h"
00041 #include "executor/nodeSeqscan.h"
00042 #include "executor/nodeSetOp.h"
00043 #include "executor/nodeSort.h"
00044 #include "executor/nodeSubplan.h"
00045 #include "executor/nodeSubqueryscan.h"
00046 #include "executor/nodeTidscan.h"
00047 #include "executor/nodeUnique.h"
00048 #include "executor/nodeValuesscan.h"
00049 #include "executor/nodeWindowAgg.h"
00050 #include "executor/nodeWorktablescan.h"
00051 #include "nodes/nodeFuncs.h"
00052 #include "utils/rel.h"
00053 #include "utils/syscache.h"
00054
00055
00056 static bool TargetListSupportsBackwardScan(List *targetlist);
00057 static bool IndexSupportsBackwardScan(Oid indexid);
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 void
00068 ExecReScan(PlanState *node)
00069 {
00070
00071 if (node->instrument)
00072 InstrEndLoop(node->instrument);
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 if (node->chgParam != NULL)
00088 {
00089 ListCell *l;
00090
00091 foreach(l, node->initPlan)
00092 {
00093 SubPlanState *sstate = (SubPlanState *) lfirst(l);
00094 PlanState *splan = sstate->planstate;
00095
00096 if (splan->plan->extParam != NULL)
00097
00098 UpdateChangedParamSet(splan, node->chgParam);
00099 if (splan->chgParam != NULL)
00100 ExecReScanSetParamPlan(sstate, node);
00101 }
00102 foreach(l, node->subPlan)
00103 {
00104 SubPlanState *sstate = (SubPlanState *) lfirst(l);
00105 PlanState *splan = sstate->planstate;
00106
00107 if (splan->plan->extParam != NULL)
00108 UpdateChangedParamSet(splan, node->chgParam);
00109 }
00110
00111 if (node->lefttree != NULL)
00112 UpdateChangedParamSet(node->lefttree, node->chgParam);
00113 if (node->righttree != NULL)
00114 UpdateChangedParamSet(node->righttree, node->chgParam);
00115 }
00116
00117
00118 if (node->ps_ExprContext)
00119 ReScanExprContext(node->ps_ExprContext);
00120
00121
00122 switch (nodeTag(node))
00123 {
00124 case T_ResultState:
00125 ExecReScanResult((ResultState *) node);
00126 break;
00127
00128 case T_ModifyTableState:
00129 ExecReScanModifyTable((ModifyTableState *) node);
00130 break;
00131
00132 case T_AppendState:
00133 ExecReScanAppend((AppendState *) node);
00134 break;
00135
00136 case T_MergeAppendState:
00137 ExecReScanMergeAppend((MergeAppendState *) node);
00138 break;
00139
00140 case T_RecursiveUnionState:
00141 ExecReScanRecursiveUnion((RecursiveUnionState *) node);
00142 break;
00143
00144 case T_BitmapAndState:
00145 ExecReScanBitmapAnd((BitmapAndState *) node);
00146 break;
00147
00148 case T_BitmapOrState:
00149 ExecReScanBitmapOr((BitmapOrState *) node);
00150 break;
00151
00152 case T_SeqScanState:
00153 ExecReScanSeqScan((SeqScanState *) node);
00154 break;
00155
00156 case T_IndexScanState:
00157 ExecReScanIndexScan((IndexScanState *) node);
00158 break;
00159
00160 case T_IndexOnlyScanState:
00161 ExecReScanIndexOnlyScan((IndexOnlyScanState *) node);
00162 break;
00163
00164 case T_BitmapIndexScanState:
00165 ExecReScanBitmapIndexScan((BitmapIndexScanState *) node);
00166 break;
00167
00168 case T_BitmapHeapScanState:
00169 ExecReScanBitmapHeapScan((BitmapHeapScanState *) node);
00170 break;
00171
00172 case T_TidScanState:
00173 ExecReScanTidScan((TidScanState *) node);
00174 break;
00175
00176 case T_SubqueryScanState:
00177 ExecReScanSubqueryScan((SubqueryScanState *) node);
00178 break;
00179
00180 case T_FunctionScanState:
00181 ExecReScanFunctionScan((FunctionScanState *) node);
00182 break;
00183
00184 case T_ValuesScanState:
00185 ExecReScanValuesScan((ValuesScanState *) node);
00186 break;
00187
00188 case T_CteScanState:
00189 ExecReScanCteScan((CteScanState *) node);
00190 break;
00191
00192 case T_WorkTableScanState:
00193 ExecReScanWorkTableScan((WorkTableScanState *) node);
00194 break;
00195
00196 case T_ForeignScanState:
00197 ExecReScanForeignScan((ForeignScanState *) node);
00198 break;
00199
00200 case T_NestLoopState:
00201 ExecReScanNestLoop((NestLoopState *) node);
00202 break;
00203
00204 case T_MergeJoinState:
00205 ExecReScanMergeJoin((MergeJoinState *) node);
00206 break;
00207
00208 case T_HashJoinState:
00209 ExecReScanHashJoin((HashJoinState *) node);
00210 break;
00211
00212 case T_MaterialState:
00213 ExecReScanMaterial((MaterialState *) node);
00214 break;
00215
00216 case T_SortState:
00217 ExecReScanSort((SortState *) node);
00218 break;
00219
00220 case T_GroupState:
00221 ExecReScanGroup((GroupState *) node);
00222 break;
00223
00224 case T_AggState:
00225 ExecReScanAgg((AggState *) node);
00226 break;
00227
00228 case T_WindowAggState:
00229 ExecReScanWindowAgg((WindowAggState *) node);
00230 break;
00231
00232 case T_UniqueState:
00233 ExecReScanUnique((UniqueState *) node);
00234 break;
00235
00236 case T_HashState:
00237 ExecReScanHash((HashState *) node);
00238 break;
00239
00240 case T_SetOpState:
00241 ExecReScanSetOp((SetOpState *) node);
00242 break;
00243
00244 case T_LockRowsState:
00245 ExecReScanLockRows((LockRowsState *) node);
00246 break;
00247
00248 case T_LimitState:
00249 ExecReScanLimit((LimitState *) node);
00250 break;
00251
00252 default:
00253 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
00254 break;
00255 }
00256
00257 if (node->chgParam != NULL)
00258 {
00259 bms_free(node->chgParam);
00260 node->chgParam = NULL;
00261 }
00262 }
00263
00264
00265
00266
00267
00268
00269 void
00270 ExecMarkPos(PlanState *node)
00271 {
00272 switch (nodeTag(node))
00273 {
00274 case T_SeqScanState:
00275 ExecSeqMarkPos((SeqScanState *) node);
00276 break;
00277
00278 case T_IndexScanState:
00279 ExecIndexMarkPos((IndexScanState *) node);
00280 break;
00281
00282 case T_IndexOnlyScanState:
00283 ExecIndexOnlyMarkPos((IndexOnlyScanState *) node);
00284 break;
00285
00286 case T_TidScanState:
00287 ExecTidMarkPos((TidScanState *) node);
00288 break;
00289
00290 case T_ValuesScanState:
00291 ExecValuesMarkPos((ValuesScanState *) node);
00292 break;
00293
00294 case T_MaterialState:
00295 ExecMaterialMarkPos((MaterialState *) node);
00296 break;
00297
00298 case T_SortState:
00299 ExecSortMarkPos((SortState *) node);
00300 break;
00301
00302 case T_ResultState:
00303 ExecResultMarkPos((ResultState *) node);
00304 break;
00305
00306 default:
00307
00308 elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
00309 break;
00310 }
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 void
00327 ExecRestrPos(PlanState *node)
00328 {
00329 switch (nodeTag(node))
00330 {
00331 case T_SeqScanState:
00332 ExecSeqRestrPos((SeqScanState *) node);
00333 break;
00334
00335 case T_IndexScanState:
00336 ExecIndexRestrPos((IndexScanState *) node);
00337 break;
00338
00339 case T_IndexOnlyScanState:
00340 ExecIndexOnlyRestrPos((IndexOnlyScanState *) node);
00341 break;
00342
00343 case T_TidScanState:
00344 ExecTidRestrPos((TidScanState *) node);
00345 break;
00346
00347 case T_ValuesScanState:
00348 ExecValuesRestrPos((ValuesScanState *) node);
00349 break;
00350
00351 case T_MaterialState:
00352 ExecMaterialRestrPos((MaterialState *) node);
00353 break;
00354
00355 case T_SortState:
00356 ExecSortRestrPos((SortState *) node);
00357 break;
00358
00359 case T_ResultState:
00360 ExecResultRestrPos((ResultState *) node);
00361 break;
00362
00363 default:
00364 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
00365 break;
00366 }
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 bool
00382 ExecSupportsMarkRestore(NodeTag plantype)
00383 {
00384 switch (plantype)
00385 {
00386 case T_SeqScan:
00387 case T_IndexScan:
00388 case T_IndexOnlyScan:
00389 case T_TidScan:
00390 case T_ValuesScan:
00391 case T_Material:
00392 case T_Sort:
00393 return true;
00394
00395 case T_Result:
00396
00397
00398
00399
00400
00401
00402
00403
00404 return false;
00405
00406 default:
00407 break;
00408 }
00409
00410 return false;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 bool
00422 ExecSupportsBackwardScan(Plan *node)
00423 {
00424 if (node == NULL)
00425 return false;
00426
00427 switch (nodeTag(node))
00428 {
00429 case T_Result:
00430 if (outerPlan(node) != NULL)
00431 return ExecSupportsBackwardScan(outerPlan(node)) &&
00432 TargetListSupportsBackwardScan(node->targetlist);
00433 else
00434 return false;
00435
00436 case T_Append:
00437 {
00438 ListCell *l;
00439
00440 foreach(l, ((Append *) node)->appendplans)
00441 {
00442 if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
00443 return false;
00444 }
00445
00446 return true;
00447 }
00448
00449 case T_SeqScan:
00450 case T_TidScan:
00451 case T_FunctionScan:
00452 case T_ValuesScan:
00453 case T_CteScan:
00454 return TargetListSupportsBackwardScan(node->targetlist);
00455
00456 case T_IndexScan:
00457 return IndexSupportsBackwardScan(((IndexScan *) node)->indexid) &&
00458 TargetListSupportsBackwardScan(node->targetlist);
00459
00460 case T_IndexOnlyScan:
00461 return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid) &&
00462 TargetListSupportsBackwardScan(node->targetlist);
00463
00464 case T_SubqueryScan:
00465 return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan) &&
00466 TargetListSupportsBackwardScan(node->targetlist);
00467
00468 case T_Material:
00469 case T_Sort:
00470
00471 return true;
00472
00473 case T_LockRows:
00474 case T_Limit:
00475
00476 return ExecSupportsBackwardScan(outerPlan(node));
00477
00478 default:
00479 return false;
00480 }
00481 }
00482
00483
00484
00485
00486
00487 static bool
00488 TargetListSupportsBackwardScan(List *targetlist)
00489 {
00490 if (expression_returns_set((Node *) targetlist))
00491 return false;
00492 return true;
00493 }
00494
00495
00496
00497
00498
00499 static bool
00500 IndexSupportsBackwardScan(Oid indexid)
00501 {
00502 bool result;
00503 HeapTuple ht_idxrel;
00504 HeapTuple ht_am;
00505 Form_pg_class idxrelrec;
00506 Form_pg_am amrec;
00507
00508
00509 ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
00510 if (!HeapTupleIsValid(ht_idxrel))
00511 elog(ERROR, "cache lookup failed for relation %u", indexid);
00512 idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
00513
00514
00515 ht_am = SearchSysCache1(AMOID, ObjectIdGetDatum(idxrelrec->relam));
00516 if (!HeapTupleIsValid(ht_am))
00517 elog(ERROR, "cache lookup failed for access method %u",
00518 idxrelrec->relam);
00519 amrec = (Form_pg_am) GETSTRUCT(ht_am);
00520
00521 result = amrec->amcanbackward;
00522
00523 ReleaseSysCache(ht_idxrel);
00524 ReleaseSysCache(ht_am);
00525
00526 return result;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 bool
00538 ExecMaterializesOutput(NodeTag plantype)
00539 {
00540 switch (plantype)
00541 {
00542 case T_Material:
00543 case T_FunctionScan:
00544 case T_CteScan:
00545 case T_WorkTableScan:
00546 case T_Sort:
00547 return true;
00548
00549 default:
00550 break;
00551 }
00552
00553 return false;
00554 }