* build_joinrel_tlist * Builds a join relation's target list from an input relation. * (This is invoked twice to handle the two input relations.) * * The join's targetlist includes all Vars of its member relations that * will still be needed above the join. This subroutine adds all such * Vars from the specified input rel's tlist to the join rel's tlist. * * We also compute the expect
| 1408 | * of data that was cached at the baserel level by set_rel_width(). |
| 1409 | */ |
| 1410 | static void |
| 1411 | build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, |
| 1412 | RelOptInfo *input_rel) |
| 1413 | { |
| 1414 | Relids relids = joinrel->relids; |
| 1415 | ListCell *vars; |
| 1416 | |
| 1417 | foreach(vars, input_rel->reltarget->exprs) |
| 1418 | { |
| 1419 | Var *var = (Var *) lfirst(vars); |
| 1420 | |
| 1421 | /* |
| 1422 | * Ignore PlaceHolderVars in the input tlists; we'll make our own |
| 1423 | * decisions about whether to copy them. |
| 1424 | */ |
| 1425 | if (IsA(var, PlaceHolderVar)) |
| 1426 | continue; |
| 1427 | |
| 1428 | /* |
| 1429 | * Otherwise, anything in a baserel or joinrel targetlist ought to be |
| 1430 | * a Var. (More general cases can only appear in appendrel child |
| 1431 | * rels, which will never be seen here.) |
| 1432 | */ |
| 1433 | if (!IsA(var, Var)) |
| 1434 | elog(ERROR, "unexpected node type in rel targetlist: %d", |
| 1435 | (int) nodeTag(var)); |
| 1436 | |
| 1437 | if (var->varno == ROWID_VAR) |
| 1438 | { |
| 1439 | /* UPDATE/DELETE row identity vars are always needed */ |
| 1440 | RowIdentityVarInfo *ridinfo = (RowIdentityVarInfo *) |
| 1441 | list_nth(root->row_identity_vars, var->varattno - 1); |
| 1442 | |
| 1443 | joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, |
| 1444 | var); |
| 1445 | /* Vars have cost zero, so no need to adjust reltarget->cost */ |
| 1446 | joinrel->reltarget->width += ridinfo->rowidwidth; |
| 1447 | } |
| 1448 | else |
| 1449 | { |
| 1450 | RelOptInfo *baserel; |
| 1451 | int ndx; |
| 1452 | |
| 1453 | /* Get the Var's original base rel */ |
| 1454 | baserel = find_base_rel(root, var->varno); |
| 1455 | |
| 1456 | /* Is it still needed above this joinrel? */ |
| 1457 | ndx = var->varattno - baserel->min_attr; |
| 1458 | if (bms_nonempty_difference(baserel->attr_needed[ndx], relids)) |
| 1459 | { |
| 1460 | /* Yup, add it to the output */ |
| 1461 | joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, |
| 1462 | var); |
| 1463 | /* Vars have cost zero, so no need to adjust reltarget->cost */ |
| 1464 | joinrel->reltarget->width += baserel->attr_widths[ndx]; |
| 1465 | } |
| 1466 | } |
| 1467 | } |
no test coverage detected