in RestrictInfo nodes, instead of recomputing on every use.
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.163 2002/02/26 22:47:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.164 2002/03/01 06:01:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
newnode->left_pathkey = NIL;
newnode->right_pathkey = NIL;
+ newnode->left_mergescansel = from->left_mergescansel;
+ newnode->right_mergescansel = from->right_mergescansel;
newnode->hashjoinoperator = from->hashjoinoperator;
newnode->left_bucketsize = from->left_bucketsize;
newnode->right_bucketsize = from->right_bucketsize;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.114 2002/02/26 22:47:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.115 2002/03/01 06:01:18 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
local_node->eval_cost = -1;
/* ditto for this_selec */
local_node->this_selec = -1;
- /* ditto for cached pathkeys and bucketsize */
+ /* ditto for cached pathkeys, selectivity, bucketsize */
local_node->left_pathkey = NIL;
local_node->right_pathkey = NIL;
+ local_node->left_mergescansel = -1;
+ local_node->right_mergescansel = -1;
local_node->left_bucketsize = -1;
local_node->right_bucketsize = -1;
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.80 2002/03/01 04:09:24 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.81 2002/03/01 06:01:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Cost startup_cost = 0;
Cost run_cost = 0;
Cost cpu_per_tuple;
+ RestrictInfo *firstclause;
double outer_rows,
inner_rows;
double ntuples;
* Estimate fraction of the left and right inputs that will actually
* need to be scanned. We use only the first (most significant)
* merge clause for this purpose.
+ *
+ * Since this calculation is somewhat expensive, and will be the same
+ * for all mergejoin paths associated with the merge clause, we cache
+ * the results in the RestrictInfo node.
*/
- mergejoinscansel(root,
- (Node *) ((RestrictInfo *) lfirst(mergeclauses))->clause,
- &leftscan, &rightscan);
+ firstclause = (RestrictInfo *) lfirst(mergeclauses);
+ if (firstclause->left_mergescansel < 0) /* not computed yet? */
+ mergejoinscansel(root, (Node *) firstclause->clause,
+ &firstclause->left_mergescansel,
+ &firstclause->right_mergescansel);
+ leftscan = firstclause->left_mergescansel;
+ rightscan = firstclause->right_mergescansel;
outer_rows = outer_path->parent->rows * leftscan;
inner_rows = inner_path->parent->rows * rightscan;
* big difference.)
*
* The "dirty" part comes from the fact that the selectivities of multiple
- * clauses are estimated independently and multiplied together. Currently,
- * clauselist_selectivity can seldom do any better than that anyhow, but
- * someday it might be smarter.
+ * clauses are estimated independently and multiplied together. Now
+ * clauselist_selectivity often can't do any better than that anyhow, but
+ * for some situations (such as range constraints) it is smarter.
*
* Since we are only using the results to estimate how many potential
* output tuples are generated and passed through qpqual checking, it
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.65 2001/10/25 05:49:33 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.66 2002/03/01 06:01:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
restrictinfo->right_sortop = InvalidOid;
restrictinfo->left_pathkey = NIL; /* not computable yet */
restrictinfo->right_pathkey = NIL;
+ restrictinfo->left_mergescansel = -1; /* not computed until needed */
+ restrictinfo->right_mergescansel = -1;
restrictinfo->hashjoinoperator = InvalidOid;
restrictinfo->left_bucketsize = -1; /* not computed until needed */
restrictinfo->right_bucketsize = -1;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.69 2001/11/12 20:04:20 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.70 2002/03/01 06:01:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
newinfo->this_selec = -1;
newinfo->left_pathkey = NIL; /* and these */
newinfo->right_pathkey = NIL;
+ newinfo->left_mergescansel = -1;
+ newinfo->right_mergescansel = -1;
newinfo->left_bucketsize = -1;
newinfo->right_bucketsize = -1;
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: relation.h,v 1.61 2001/11/05 17:46:34 momjian Exp $
+ * $Id: relation.h,v 1.62 2002/03/01 06:01:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
List *left_pathkey; /* canonical pathkey for left side */
List *right_pathkey; /* canonical pathkey for right side */
+ /* cache space for mergeclause processing; -1 if not yet set */
+ Selectivity left_mergescansel; /* fraction of left side to scan */
+ Selectivity right_mergescansel; /* fraction of right side to scan */
+
/* valid if clause is hashjoinable, else InvalidOid: */
Oid hashjoinoperator; /* copy of clause operator */