1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

Modify planner's implied-equality-deduction code so that when a set

of known-equal expressions includes any constant expressions (including
Params from outer queries), we actively suppress any 'var = var'
clauses that are or could be deduced from the set, generating only the
deducible 'var = const' clauses instead.  The idea here is to push down
the restrictions implied by the equality set to base relations whenever
possible.  Once we have applied the 'var = const' clauses, the 'var = var'
clauses are redundant, and should be suppressed both to save work at
execution and to avoid double-counting restrictivity.
This commit is contained in:
Tom Lane
2003-01-24 03:58:44 +00:00
parent ef7422510e
commit f5e83662d0
12 changed files with 395 additions and 168 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.15 2002/11/24 21:52:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.16 2003/01/24 03:58:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,6 +17,7 @@
#include "optimizer/clauses.h"
#include "optimizer/paths.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/var.h"
/*
@@ -101,6 +102,13 @@ get_actual_join_clauses(List *restrictinfo_list,
* equality between any set member on the left and any member on the right;
* by transitivity, all the rest are then equal.
*
* However, clauses that are of the form "var expr = const expr" cannot be
* eliminated as redundant. This is because when there are const expressions
* in a pathkey set, generate_implied_equalities() suppresses "var = var"
* clauses in favor of "var = const" clauses. We cannot afford to drop any
* of the latter, even though they might seem redundant by the pathkey
* membership test.
*
* Weird special case: if we have two clauses that seem redundant
* except one is pushed down into an outer join and the other isn't,
* then they're not really redundant, because one constrains the
@@ -120,7 +128,7 @@ remove_redundant_join_clauses(Query *root, List *restrictinfo_list,
{
RestrictInfo *rinfo = (RestrictInfo *) lfirst(item);
/* eliminate duplicates */
/* always eliminate duplicates */
if (member(rinfo, result))
continue;
@@ -132,6 +140,7 @@ remove_redundant_join_clauses(Query *root, List *restrictinfo_list,
cache_mergeclause_pathkeys(root, rinfo);
/* do the cheap tests first */
foreach(olditem, result)
{
RestrictInfo *oldrinfo = (RestrictInfo *) lfirst(olditem);
@@ -148,7 +157,20 @@ remove_redundant_join_clauses(Query *root, List *restrictinfo_list,
}
if (redundant)
continue;
{
/*
* It looks redundant, now check for "var = const" case.
* If left_relids/right_relids are set, then there are
* definitely vars on both sides; else we must check the
* hard way.
*/
if (rinfo->left_relids)
continue; /* var = var, so redundant */
if (contain_var_clause(get_leftop(rinfo->clause)) &&
contain_var_clause(get_rightop(rinfo->clause)))
continue; /* var = var, so redundant */
/* else var = const, not redundant */
}
}
/* otherwise, add it to result list */