|
6 | 6 | * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
7 | 7 | * Portions Copyright (c) 1994, Regents of the University of California
|
8 | 8 | *
|
9 |
| - * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.77 2003/12/18 20:21:37 tgl Exp $ |
| 9 | + * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.78 2004/03/02 18:56:15 tgl Exp $ |
10 | 10 | *
|
11 | 11 | *-------------------------------------------------------------------------
|
12 | 12 | */
|
@@ -348,3 +348,68 @@ ExecSupportsBackwardScan(Plan *node)
|
348 | 348 | return false;
|
349 | 349 | }
|
350 | 350 | }
|
| 351 | + |
| 352 | +/* |
| 353 | + * ExecMayReturnRawTuples |
| 354 | + * Check whether a plan tree may return "raw" disk tuples (that is, |
| 355 | + * pointers to original data in disk buffers, as opposed to temporary |
| 356 | + * tuples constructed by projection steps). In the case of Append, |
| 357 | + * some subplans may return raw tuples and others projected tuples; |
| 358 | + * we return "true" if any of the returned tuples could be raw. |
| 359 | + * |
| 360 | + * This must be passed an already-initialized planstate tree, because we |
| 361 | + * need to look at the results of ExecAssignScanProjectionInfo(). |
| 362 | + */ |
| 363 | +bool |
| 364 | +ExecMayReturnRawTuples(PlanState *node) |
| 365 | +{ |
| 366 | + /* |
| 367 | + * At a table scan node, we check whether ExecAssignScanProjectionInfo |
| 368 | + * decided to do projection or not. Most non-scan nodes always project |
| 369 | + * and so we can return "false" immediately. For nodes that don't |
| 370 | + * project but just pass up input tuples, we have to recursively |
| 371 | + * examine the input plan node. |
| 372 | + * |
| 373 | + * Note: Hash and Material are listed here because they sometimes |
| 374 | + * return an original input tuple, not a copy. But Sort and SetOp |
| 375 | + * never return an original tuple, so they can be treated like |
| 376 | + * projecting nodes. |
| 377 | + */ |
| 378 | + switch (nodeTag(node)) |
| 379 | + { |
| 380 | + /* Table scan nodes */ |
| 381 | + case T_SeqScanState: |
| 382 | + case T_IndexScanState: |
| 383 | + case T_TidScanState: |
| 384 | + case T_SubqueryScanState: |
| 385 | + case T_FunctionScanState: |
| 386 | + if (node->ps_ProjInfo == NULL) |
| 387 | + return true; |
| 388 | + break; |
| 389 | + |
| 390 | + /* Non-projecting nodes */ |
| 391 | + case T_HashState: |
| 392 | + case T_MaterialState: |
| 393 | + case T_UniqueState: |
| 394 | + case T_LimitState: |
| 395 | + return ExecMayReturnRawTuples(node->lefttree); |
| 396 | + |
| 397 | + case T_AppendState: |
| 398 | + { |
| 399 | + AppendState *appendstate = (AppendState *) node; |
| 400 | + int j; |
| 401 | + |
| 402 | + for (j = 0; j < appendstate->as_nplans; j++) |
| 403 | + { |
| 404 | + if (ExecMayReturnRawTuples(appendstate->appendplans[j])) |
| 405 | + return true; |
| 406 | + } |
| 407 | + break; |
| 408 | + } |
| 409 | + |
| 410 | + /* All projecting node types come here */ |
| 411 | + default: |
| 412 | + break; |
| 413 | + } |
| 414 | + return false; |
| 415 | +} |
0 commit comments