641
651
if (IS_DUMMY_REL(childrel))
654
/* We have at least one live child. */
655
has_live_children = true;
645
658
* Accumulate size information from each live child.
647
if (childrel->rows > 0)
660
Assert(childrel->rows > 0);
662
parent_rows += childrel->rows;
663
parent_size += childrel->width * childrel->rows;
666
* Accumulate per-column estimates too. We need not do anything for
667
* PlaceHolderVars in the parent list. If child expression isn't a
668
* Var, or we didn't record a width estimate for it, we have to fall
669
* back on a datatype-based estimate.
671
* By construction, child's reltargetlist is 1-to-1 with parent's.
673
forboth(parentvars, rel->reltargetlist,
674
childvars, childrel->reltargetlist)
649
parent_rows += childrel->rows;
650
parent_size += childrel->width * childrel->rows;
676
Var *parentvar = (Var *) lfirst(parentvars);
677
Node *childvar = (Node *) lfirst(childvars);
653
* Accumulate per-column estimates too. We need not do anything
654
* for PlaceHolderVars in the parent list. If child expression
655
* isn't a Var, or we didn't record a width estimate for it, we
656
* have to fall back on a datatype-based estimate.
658
* By construction, child's reltargetlist is 1-to-1 with parent's.
660
forboth(parentvars, rel->reltargetlist,
661
childvars, childrel->reltargetlist)
679
if (IsA(parentvar, Var))
663
Var *parentvar = (Var *) lfirst(parentvars);
664
Node *childvar = (Node *) lfirst(childvars);
681
int pndx = parentvar->varattno - rel->min_attr;
682
int32 child_width = 0;
666
if (IsA(parentvar, Var))
684
if (IsA(childvar, Var) &&
685
((Var *) childvar)->varno == childrel->relid)
668
int pndx = parentvar->varattno - rel->min_attr;
669
int32 child_width = 0;
671
if (IsA(childvar, Var) &&
672
((Var *) childvar)->varno == childrel->relid)
674
int cndx = ((Var *) childvar)->varattno - childrel->min_attr;
676
child_width = childrel->attr_widths[cndx];
678
if (child_width <= 0)
679
child_width = get_typavgwidth(exprType(childvar),
680
exprTypmod(childvar));
681
Assert(child_width > 0);
682
parent_attrsizes[pndx] += child_width * childrel->rows;
687
int cndx = ((Var *) childvar)->varattno - childrel->min_attr;
689
child_width = childrel->attr_widths[cndx];
691
if (child_width <= 0)
692
child_width = get_typavgwidth(exprType(childvar),
693
exprTypmod(childvar));
694
Assert(child_width > 0);
695
parent_attrsizes[pndx] += child_width * childrel->rows;
689
* Save the finished size estimates.
691
rel->rows = parent_rows;
700
if (has_live_children)
703
* Save the finished size estimates.
707
Assert(parent_rows > 0);
708
rel->rows = parent_rows;
696
709
rel->width = rint(parent_size / parent_rows);
697
710
for (i = 0; i < nattrs; i++)
698
711
rel->attr_widths[i] = rint(parent_attrsizes[i] / parent_rows);
714
* Set "raw tuples" count equal to "rows" for the appendrel; needed
715
* because some places assume rel->tuples is valid for any baserel.
717
rel->tuples = parent_rows;
701
rel->width = 0; /* attr_widths should be zero already */
704
* Set "raw tuples" count equal to "rows" for the appendrel; needed
705
* because some places assume rel->tuples is valid for any baserel.
707
rel->tuples = parent_rows;
722
* All children were excluded by constraints, so mark the whole
723
* appendrel dummy. We must do this in this phase so that the rel's
724
* dummy-ness is visible when we generate paths for other rels.
726
set_dummy_rel_pathlist(rel);
709
729
pfree(parent_attrsizes);