|
12 | 12 | #include "nodes_common.h" |
13 | 13 | #include "runtimeappend.h" |
14 | 14 | #include "optimizer/restrictinfo.h" |
15 | | - |
| 15 | +#include "optimizer/plancat.h" |
| 16 | +#include "utils/memutils.h" |
| 17 | +#include "utils.h" |
16 | 18 |
|
17 | 19 |
|
18 | 20 | /* Compare plans by 'original_order' */ |
@@ -275,6 +277,21 @@ create_append_plan_common(PlannerInfo *root, RelOptInfo *rel, |
275 | 277 | RuntimeAppendPath *gpath = (RuntimeAppendPath *) best_path; |
276 | 278 | CustomScan *cscan; |
277 | 279 |
|
| 280 | + /* HACK: kill me plz, it severely breaks IndexOnlyScan */ |
| 281 | + if (custom_plans) |
| 282 | + { |
| 283 | + ListCell *lc1, |
| 284 | + *lc2; |
| 285 | + |
| 286 | + forboth (lc1, gpath->cpath.custom_paths, lc2, custom_plans) |
| 287 | + { |
| 288 | + Plan *child_plan = (Plan *) lfirst(lc2); |
| 289 | + RelOptInfo *child_rel = ((Path *) lfirst(lc1))->parent; |
| 290 | + |
| 291 | + child_plan->targetlist = build_physical_tlist(root, child_rel); |
| 292 | + } |
| 293 | + } |
| 294 | + |
278 | 295 | cscan = makeNode(CustomScan); |
279 | 296 | cscan->scan.plan.qual = NIL; |
280 | 297 | cscan->scan.plan.targetlist = tlist; |
@@ -324,6 +341,51 @@ begin_append_common(CustomScanState *node, EState *estate, int eflags) |
324 | 341 | scan_state->custom_expr_states = |
325 | 342 | (List *) ExecInitExpr((Expr *) scan_state->custom_exprs, |
326 | 343 | (PlanState *) scan_state); |
| 344 | + |
| 345 | + node->ss.ps.ps_TupFromTlist = false; |
| 346 | +} |
| 347 | + |
| 348 | +TupleTableSlot * |
| 349 | +exec_append_common(CustomScanState *node, |
| 350 | + void (*fetch_next_tuple) (CustomScanState *node)) |
| 351 | +{ |
| 352 | + RuntimeAppendState *scan_state = (RuntimeAppendState *) node; |
| 353 | + |
| 354 | + if (scan_state->ncur_plans == 0) |
| 355 | + ExecReScan(&node->ss.ps); |
| 356 | + |
| 357 | + for (;;) |
| 358 | + { |
| 359 | + if (!node->ss.ps.ps_TupFromTlist) |
| 360 | + { |
| 361 | + fetch_next_tuple(node); |
| 362 | + |
| 363 | + if (TupIsNull(scan_state->slot)) |
| 364 | + return NULL; |
| 365 | + } |
| 366 | + |
| 367 | + if (node->ss.ps.ps_ProjInfo) |
| 368 | + { |
| 369 | + ExprDoneCond isDone; |
| 370 | + TupleTableSlot *result; |
| 371 | + |
| 372 | + ResetExprContext(node->ss.ps.ps_ExprContext); |
| 373 | + |
| 374 | + node->ss.ps.ps_ProjInfo->pi_exprContext->ecxt_scantuple = scan_state->slot; |
| 375 | + result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone); |
| 376 | + |
| 377 | + if (isDone != ExprEndResult) |
| 378 | + { |
| 379 | + node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult); |
| 380 | + |
| 381 | + return result; |
| 382 | + } |
| 383 | + else |
| 384 | + node->ss.ps.ps_TupFromTlist = false; |
| 385 | + } |
| 386 | + else |
| 387 | + return scan_state->slot; |
| 388 | + } |
327 | 389 | } |
328 | 390 |
|
329 | 391 | void |
|
0 commit comments