numGroups = estimate_num_groups(root,
get_sortgrouplist_exprs(root->parse->groupClause,
fpinfo->grouped_tlist),
- input_rows, NULL);
+ input_rows, NULL, NULL);
/*
* Get the retrieved_rows and rows estimates. If there are HAVING
/* Estimate number of groups with equal presorted keys. */
if (!unknown_varno)
- input_groups = estimate_num_groups(root, presortedExprs, input_tuples, NULL);
+ input_groups = estimate_num_groups(root, presortedExprs, input_tuples,
+ NULL, NULL);
group_tuples = input_tuples / input_groups;
group_input_run_cost = input_run_cost / input_groups;
nunique = estimate_num_groups(root,
sjinfo->semi_rhs_exprs,
nraw,
+ NULL,
NULL);
if (rowcount > nunique)
rowcount = nunique;
double numGroups = estimate_num_groups(root,
groupExprs,
path_rows,
- &gset);
+ &gset,
+ NULL);
gs->numGroups = numGroups;
rollup->numGroups += numGroups;
double numGroups = estimate_num_groups(root,
groupExprs,
path_rows,
- &gset);
+ &gset,
+ NULL);
gs->numGroups = numGroups;
gd->dNumHashGroups += numGroups;
target_list);
dNumGroups = estimate_num_groups(root, groupExprs, path_rows,
- NULL);
+ NULL, NULL);
}
}
else if (parse->groupingSets)
parse->targetList);
numDistinctRows = estimate_num_groups(root, distinctExprs,
cheapest_input_path->rows,
- NULL);
+ NULL, NULL);
}
/*
*pNumGroups = estimate_num_groups(subroot,
get_tlist_exprs(subquery->targetList, false),
subpath->rows,
+ NULL,
NULL);
}
}
pathnode->path.rows = estimate_num_groups(root,
sjinfo->semi_rhs_exprs,
rel->rows,
+ NULL,
NULL);
numCols = list_length(sjinfo->semi_rhs_exprs);
Node *var; /* might be an expression, not just a Var */
RelOptInfo *rel; /* relation it belongs to */
double ndistinct; /* # distinct values */
+ bool isdefault; /* true if DEFAULT_NUM_DISTINCT was used */
} GroupVarInfo;
static List *
varinfo->var = var;
varinfo->rel = vardata->rel;
varinfo->ndistinct = ndistinct;
+ varinfo->isdefault = isdefault;
varinfos = lappend(varinfos, varinfo);
return varinfos;
}
* pgset - NULL, or a List** pointing to a grouping set to filter the
* groupExprs against
*
+ * Outputs:
+ * estinfo - When passed as non-NULL, the function will set bits in the
+ * "flags" field in order to provide callers with additional information
+ * about the estimation. Currently, we only set the SELFLAG_USED_DEFAULT
+ * bit if we used any default values in the estimation.
+ *
* Given the lack of any cross-correlation statistics in the system, it's
* impossible to do anything really trustworthy with GROUP BY conditions
* involving multiple Vars. We should however avoid assuming the worst
*/
double
estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows,
- List **pgset)
+ List **pgset, EstimationInfo *estinfo)
{
List *varinfos = NIL;
double srf_multiplier = 1.0;
ListCell *l;
int i;
+ /* Zero the estinfo output parameter, if non-NULL */
+ if (estinfo != NULL)
+ memset(estinfo, 0, sizeof(EstimationInfo));
+
/*
* We don't ever want to return an estimate of zero groups, as that tends
* to lead to division-by-zero and other unpleasantness. The input_rows
if (relmaxndistinct < varinfo2->ndistinct)
relmaxndistinct = varinfo2->ndistinct;
relvarcount++;
+
+ /*
+ * When varinfo2's isdefault is set then we'd better set
+ * the SELFLAG_USED_DEFAULT bit in the EstimationInfo.
+ */
+ if (estinfo != NULL && varinfo2->isdefault)
+ estinfo->flags |= SELFLAG_USED_DEFAULT;
+
}
/* we're done with this relation */
p = 1.0; \
} while (0)
+/*
+ * A set of flags which some selectivity estimation functions can pass back to
+ * callers to provide further details about some assumptions which were made
+ * during the estimation.
+ */
+#define SELFLAG_USED_DEFAULT (1 << 0) /* Estimation fell back on one
+ * of the DEFAULTs as defined
+ * above. */
+
+typedef struct EstimationInfo
+{
+ uint32 flags; /* Flags, as defined above to mark special
+ * properties of the estimation. */
+} EstimationInfo;
/* Return data from examine_variable and friends */
typedef struct VariableStatData
Selectivity *rightstart, Selectivity *rightend);
extern double estimate_num_groups(PlannerInfo *root, List *groupExprs,
- double input_rows, List **pgset);
+ double input_rows, List **pgset,
+ EstimationInfo *estinfo);
extern void estimate_hash_bucket_stats(PlannerInfo *root,
Node *hashkey, double nbuckets,