1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* joinutils.c--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Utilities for matching and building join and path keys
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
1999-02-10 18:14:32 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/joinutils.c,v 1.15 1999/02/10 17:14:30 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
|
|
|
#include "nodes/pg_list.h"
|
|
|
|
#include "nodes/relation.h"
|
|
|
|
#include "nodes/plannodes.h"
|
|
|
|
|
|
|
|
#include "optimizer/internal.h"
|
|
|
|
#include "optimizer/paths.h"
|
|
|
|
#include "optimizer/var.h"
|
|
|
|
#include "optimizer/keys.h"
|
|
|
|
#include "optimizer/tlist.h"
|
|
|
|
#include "optimizer/joininfo.h"
|
|
|
|
#include "optimizer/ordering.h"
|
|
|
|
|
|
|
|
|
1998-09-01 06:40:42 +02:00
|
|
|
static int match_pathkey_joinkeys(List *pathkey, List *joinkeys,
|
1999-02-10 18:14:32 +01:00
|
|
|
int which_subkey);
|
1998-09-01 06:40:42 +02:00
|
|
|
static bool every_func(List *joinkeys, List *pathkey,
|
1999-02-10 18:14:32 +01:00
|
|
|
int which_subkey);
|
|
|
|
static List *new_join_pathkey(List *subkeys, List *considered_subkeys,
|
|
|
|
List *join_rel_tlist, List *joinclauses);
|
1998-09-01 06:40:42 +02:00
|
|
|
static List *new_matching_subkeys(Var *subkey, List *considered_subkeys,
|
1999-02-10 18:14:32 +01:00
|
|
|
List *join_rel_tlist, List *joinclauses);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
1997-09-07 07:04:48 +02:00
|
|
|
* KEY COMPARISONS
|
1996-07-09 08:22:35 +02:00
|
|
|
****************************************************************************/
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* match-pathkeys-joinkeys--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Attempts to match the keys of a path against the keys of join clauses.
|
|
|
|
* This is done by looking for a matching join key in 'joinkeys' for
|
1999-02-10 04:52:54 +01:00
|
|
|
* every path key in the list 'path.keys'. If there is a matching join key
|
1997-09-07 07:04:48 +02:00
|
|
|
* (not necessarily unique) for every path key, then the list of
|
|
|
|
* corresponding join keys and join clauses are returned in the order in
|
|
|
|
* which the keys matched the path keys.
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'pathkeys' is a list of path keys:
|
1997-09-07 07:04:48 +02:00
|
|
|
* ( ( (var) (var) ... ) ( (var) ... ) )
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'joinkeys' is a list of join keys:
|
1997-09-07 07:04:48 +02:00
|
|
|
* ( (outer inner) (outer inner) ... )
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'joinclauses' is a list of clauses corresponding to the join keys in
|
1997-09-07 07:04:48 +02:00
|
|
|
* 'joinkeys'
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'which-subkey' is a flag that selects the desired subkey of a join key
|
1997-09-07 07:04:48 +02:00
|
|
|
* in 'joinkeys'
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* Returns the join keys and corresponding join clauses in a list if all
|
|
|
|
* of the path keys were matched:
|
1997-09-07 07:04:48 +02:00
|
|
|
* (
|
|
|
|
* ( (outerkey0 innerkey0) ... (outerkeyN innerkeyN) )
|
|
|
|
* ( clause0 ... clauseN )
|
|
|
|
* )
|
1996-07-09 08:22:35 +02:00
|
|
|
* and nil otherwise.
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* Returns a list of matched join keys and a list of matched join clauses
|
|
|
|
* in matchedJoinClausesPtr. - ay 11/94
|
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
List *
|
1997-09-08 23:56:23 +02:00
|
|
|
match_pathkeys_joinkeys(List *pathkeys,
|
|
|
|
List *joinkeys,
|
|
|
|
List *joinclauses,
|
1997-09-07 07:04:48 +02:00
|
|
|
int which_subkey,
|
1997-09-08 23:56:23 +02:00
|
|
|
List **matchedJoinClausesPtr)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *matched_joinkeys = NIL;
|
|
|
|
List *matched_joinclauses = NIL;
|
|
|
|
List *pathkey = NIL;
|
|
|
|
List *i = NIL;
|
|
|
|
int matched_joinkey_index = -1;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(i, pathkeys)
|
|
|
|
{
|
|
|
|
pathkey = lfirst(i);
|
1999-02-03 22:18:02 +01:00
|
|
|
matched_joinkey_index = match_pathkey_joinkeys(pathkey, joinkeys, which_subkey);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (matched_joinkey_index != -1)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *xjoinkey = nth(matched_joinkey_index, joinkeys);
|
|
|
|
List *joinclause = nth(matched_joinkey_index, joinclauses);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
/* XXX was "push" function */
|
|
|
|
matched_joinkeys = lappend(matched_joinkeys, xjoinkey);
|
|
|
|
matched_joinkeys = nreverse(matched_joinkeys);
|
|
|
|
|
|
|
|
matched_joinclauses = lappend(matched_joinclauses, joinclause);
|
|
|
|
matched_joinclauses = nreverse(matched_joinclauses);
|
|
|
|
joinkeys = LispRemove(xjoinkey, joinkeys);
|
|
|
|
}
|
|
|
|
else
|
1998-09-01 05:29:17 +02:00
|
|
|
return NIL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
if (matched_joinkeys == NULL ||
|
|
|
|
length(matched_joinkeys) != length(pathkeys))
|
|
|
|
return NIL;
|
|
|
|
|
|
|
|
*matchedJoinClausesPtr = nreverse(matched_joinclauses);
|
1998-09-01 05:29:17 +02:00
|
|
|
return nreverse(matched_joinkeys);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* match-pathkey-joinkeys--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns the 0-based index into 'joinkeys' of the first joinkey whose
|
|
|
|
* outer or inner subkey matches any subkey of 'pathkey'.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
static int
|
1997-09-08 23:56:23 +02:00
|
|
|
match_pathkey_joinkeys(List *pathkey,
|
|
|
|
List *joinkeys,
|
1997-09-07 07:04:48 +02:00
|
|
|
int which_subkey)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Var *path_subkey;
|
|
|
|
int pos;
|
|
|
|
List *i = NIL;
|
|
|
|
List *x = NIL;
|
|
|
|
JoinKey *jk;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(i, pathkey)
|
|
|
|
{
|
|
|
|
path_subkey = (Var *) lfirst(i);
|
|
|
|
pos = 0;
|
|
|
|
foreach(x, joinkeys)
|
|
|
|
{
|
|
|
|
jk = (JoinKey *) lfirst(x);
|
|
|
|
if (var_equal(path_subkey,
|
|
|
|
extract_subkey(jk, which_subkey)))
|
1998-09-01 05:29:17 +02:00
|
|
|
return pos;
|
1997-09-07 07:04:48 +02:00
|
|
|
pos++;
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1998-09-01 06:40:42 +02:00
|
|
|
return -1; /* no index found */
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* match-paths-joinkeys--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Attempts to find a path in 'paths' whose keys match a set of join
|
|
|
|
* keys 'joinkeys'. To match,
|
|
|
|
* 1. the path node ordering must equal 'ordering'.
|
|
|
|
* 2. each subkey of a given path must match(i.e., be(var_equal) to) the
|
|
|
|
* appropriate subkey of the corresponding join key in 'joinkeys',
|
|
|
|
* i.e., the Nth path key must match its subkeys against the subkey of
|
|
|
|
* the Nth join key in 'joinkeys'.
|
|
|
|
*
|
|
|
|
* 'joinkeys' is the list of key pairs to which the path keys must be
|
|
|
|
* matched
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'ordering' is the ordering of the(outer) path to which 'joinkeys'
|
1997-09-07 07:04:48 +02:00
|
|
|
* must correspond
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'paths' is a list of(inner) paths which are to be matched against
|
1997-09-07 07:04:48 +02:00
|
|
|
* each join key in 'joinkeys'
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'which-subkey' is a flag that selects the desired subkey of a join key
|
1997-09-07 07:04:48 +02:00
|
|
|
* in 'joinkeys'
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* Returns the matching path node if one exists, nil otherwise.
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static bool
|
1997-09-08 23:56:23 +02:00
|
|
|
every_func(List *joinkeys, List *pathkey, int which_subkey)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
JoinKey *xjoinkey;
|
|
|
|
Var *temp;
|
|
|
|
Var *tempkey = NULL;
|
|
|
|
bool found = false;
|
|
|
|
List *i = NIL;
|
|
|
|
List *j = NIL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(i, joinkeys)
|
|
|
|
{
|
|
|
|
xjoinkey = (JoinKey *) lfirst(i);
|
|
|
|
found = false;
|
|
|
|
foreach(j, pathkey)
|
|
|
|
{
|
|
|
|
temp = (Var *) lfirst((List *) lfirst(j));
|
|
|
|
if (temp == NULL)
|
|
|
|
continue;
|
|
|
|
tempkey = extract_subkey(xjoinkey, which_subkey);
|
|
|
|
if (var_equal(tempkey, temp))
|
|
|
|
{
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found == false)
|
1998-09-01 05:29:17 +02:00
|
|
|
return false;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1998-09-01 05:29:17 +02:00
|
|
|
return found;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* match_paths_joinkeys -
|
1997-09-07 07:04:48 +02:00
|
|
|
* find the cheapest path that matches the join keys
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
Path *
|
1997-09-08 23:56:23 +02:00
|
|
|
match_paths_joinkeys(List *joinkeys,
|
|
|
|
PathOrder *ordering,
|
|
|
|
List *paths,
|
1997-09-07 07:04:48 +02:00
|
|
|
int which_subkey)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Path *matched_path = NULL;
|
|
|
|
bool key_match = false;
|
|
|
|
List *i = NIL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(i, paths)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Path *path = (Path *) lfirst(i);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1999-02-10 04:52:54 +01:00
|
|
|
key_match = every_func(joinkeys, path->pathkeys, which_subkey);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1999-02-09 04:51:42 +01:00
|
|
|
if (equal_path_ordering(ordering, path->path_order) &&
|
1999-02-10 18:14:32 +01:00
|
|
|
length(joinkeys) == length(path->pathkeys) && key_match)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
if (matched_path)
|
|
|
|
{
|
|
|
|
if (path->path_cost < matched_path->path_cost)
|
|
|
|
matched_path = path;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
matched_path = path;
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
return matched_path;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* extract-path-keys--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Builds a subkey list for a path by pulling one of the subkeys from
|
|
|
|
* a list of join keys 'joinkeys' and then finding the var node in the
|
|
|
|
* target list 'tlist' that corresponds to that subkey.
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'joinkeys' is a list of join key pairs
|
|
|
|
* 'tlist' is a relation target list
|
|
|
|
* 'which-subkey' is a flag that selects the desired subkey of a join key
|
1997-09-07 07:04:48 +02:00
|
|
|
* in 'joinkeys'
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* Returns a list of pathkeys: ((tlvar1)(tlvar2)...(tlvarN)).
|
1999-02-10 04:52:54 +01:00
|
|
|
* It is a list of lists because of multi-key indexes.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
List *
|
1997-09-08 23:56:23 +02:00
|
|
|
extract_path_keys(List *joinkeys,
|
|
|
|
List *tlist,
|
1997-09-07 07:04:48 +02:00
|
|
|
int which_subkey)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *pathkeys = NIL;
|
|
|
|
List *jk;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(jk, joinkeys)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
JoinKey *jkey = (JoinKey *) lfirst(jk);
|
|
|
|
Var *var,
|
|
|
|
*key;
|
|
|
|
List *p;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
|
|
|
* find the right Var in the target list for this key
|
|
|
|
*/
|
|
|
|
var = (Var *) extract_subkey(jkey, which_subkey);
|
|
|
|
key = (Var *) matching_tlvar(var, tlist);
|
|
|
|
|
|
|
|
/*
|
1999-02-10 18:14:32 +01:00
|
|
|
* Include it in the pathkeys list if we haven't already done so
|
1997-09-07 07:04:48 +02:00
|
|
|
*/
|
|
|
|
foreach(p, pathkeys)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Var *pkey = lfirst((List *) lfirst(p)); /* XXX fix me */
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (key == pkey)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (p != NIL)
|
|
|
|
continue; /* key already in pathkeys */
|
|
|
|
|
1999-02-03 22:18:02 +01:00
|
|
|
pathkeys = lappend(pathkeys, lcons(key, NIL));
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1998-09-01 05:29:17 +02:00
|
|
|
return pathkeys;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
1997-09-07 07:04:48 +02:00
|
|
|
* NEW PATHKEY FORMATION
|
1996-07-09 08:22:35 +02:00
|
|
|
****************************************************************************/
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* new-join-pathkeys--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Find the path keys for a join relation by finding all vars in the list
|
|
|
|
* of join clauses 'joinclauses' such that:
|
|
|
|
* (1) the var corresponding to the outer join relation is a
|
|
|
|
* key on the outer path
|
|
|
|
* (2) the var appears in the target list of the join relation
|
|
|
|
* In other words, add to each outer path key the inner path keys that
|
|
|
|
* are required for qualification.
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'outer-pathkeys' is the list of the outer path's path keys
|
|
|
|
* 'join-rel-tlist' is the target list of the join relation
|
|
|
|
* 'joinclauses' is the list of restricting join clauses
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
|
|
|
* Returns the list of new path keys.
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
List *
|
1997-09-08 23:56:23 +02:00
|
|
|
new_join_pathkeys(List *outer_pathkeys,
|
|
|
|
List *join_rel_tlist,
|
|
|
|
List *joinclauses)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *outer_pathkey = NIL;
|
|
|
|
List *t_list = NIL;
|
|
|
|
List *x;
|
|
|
|
List *i = NIL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(i, outer_pathkeys)
|
|
|
|
{
|
|
|
|
outer_pathkey = lfirst(i);
|
1999-02-09 18:03:14 +01:00
|
|
|
x = new_join_pathkey(outer_pathkey, NIL, join_rel_tlist, joinclauses);
|
1997-09-07 07:04:48 +02:00
|
|
|
if (x != NIL)
|
|
|
|
t_list = lappend(t_list, x);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1998-09-01 05:29:17 +02:00
|
|
|
return t_list;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* new-join-pathkey--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Finds new vars that become subkeys due to qualification clauses that
|
|
|
|
* contain any previously considered subkeys. These new subkeys plus the
|
|
|
|
* subkeys from 'subkeys' form a new pathkey for the join relation.
|
|
|
|
*
|
|
|
|
* Note that each returned subkey is the var node found in
|
|
|
|
* 'join-rel-tlist' rather than the joinclause var node.
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'subkeys' is a list of subkeys for which matching subkeys are to be
|
1997-09-07 07:04:48 +02:00
|
|
|
* found
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'considered-subkeys' is the current list of all subkeys corresponding
|
1997-09-07 07:04:48 +02:00
|
|
|
* to a given pathkey
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* Returns a new pathkey(list of subkeys).
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static List *
|
1997-09-08 23:56:23 +02:00
|
|
|
new_join_pathkey(List *subkeys,
|
|
|
|
List *considered_subkeys,
|
|
|
|
List *join_rel_tlist,
|
|
|
|
List *joinclauses)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *t_list = NIL;
|
|
|
|
Var *subkey;
|
|
|
|
List *i = NIL;
|
|
|
|
List *matched_subkeys = NIL;
|
|
|
|
Expr *tlist_key = (Expr *) NULL;
|
|
|
|
List *newly_considered_subkeys = NIL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(i, subkeys)
|
|
|
|
{
|
|
|
|
subkey = (Var *) lfirst(i);
|
|
|
|
if (subkey == NULL)
|
|
|
|
break; /* XXX something is wrong */
|
1999-02-03 22:18:02 +01:00
|
|
|
matched_subkeys = new_matching_subkeys(subkey, considered_subkeys,
|
1997-09-07 07:04:48 +02:00
|
|
|
join_rel_tlist, joinclauses);
|
|
|
|
tlist_key = matching_tlvar(subkey, join_rel_tlist);
|
|
|
|
newly_considered_subkeys = NIL;
|
|
|
|
|
|
|
|
if (tlist_key)
|
|
|
|
{
|
|
|
|
if (!member(tlist_key, matched_subkeys))
|
|
|
|
newly_considered_subkeys = lcons(tlist_key,
|
|
|
|
matched_subkeys);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
newly_considered_subkeys = matched_subkeys;
|
|
|
|
|
1999-02-10 18:14:32 +01:00
|
|
|
considered_subkeys = append(considered_subkeys, newly_considered_subkeys);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
t_list = nconc(t_list, newly_considered_subkeys);
|
|
|
|
}
|
1998-09-01 05:29:17 +02:00
|
|
|
return t_list;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* new-matching-subkeys--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns a list of new subkeys:
|
|
|
|
* (1) which are not listed in 'considered-subkeys'
|
|
|
|
* (2) for which the "other" variable in some clause in 'joinclauses' is
|
|
|
|
* 'subkey'
|
|
|
|
* (3) which are mentioned in 'join-rel-tlist'
|
|
|
|
*
|
|
|
|
* Note that each returned subkey is the var node found in
|
|
|
|
* 'join-rel-tlist' rather than the joinclause var node.
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'subkey' is the var node for which we are trying to find matching
|
1997-09-07 07:04:48 +02:00
|
|
|
* clauses
|
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* Returns a list of new subkeys.
|
|
|
|
*
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static List *
|
1997-09-08 23:56:23 +02:00
|
|
|
new_matching_subkeys(Var *subkey,
|
|
|
|
List *considered_subkeys,
|
|
|
|
List *join_rel_tlist,
|
|
|
|
List *joinclauses)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Expr *joinclause = NULL;
|
|
|
|
List *t_list = NIL;
|
|
|
|
List *temp = NIL;
|
|
|
|
List *i = NIL;
|
|
|
|
Expr *tlist_other_var = (Expr *) NULL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(i, joinclauses)
|
|
|
|
{
|
|
|
|
joinclause = lfirst(i);
|
1999-02-09 18:03:14 +01:00
|
|
|
tlist_other_var = matching_tlvar(
|
|
|
|
other_join_clause_var(subkey, joinclause),
|
|
|
|
join_rel_tlist);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (tlist_other_var &&
|
|
|
|
!(member(tlist_other_var, considered_subkeys)))
|
|
|
|
{
|
|
|
|
|
|
|
|
/* XXX was "push" function */
|
|
|
|
considered_subkeys = lappend(considered_subkeys,
|
|
|
|
tlist_other_var);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* considered_subkeys = nreverse(considered_subkeys); XXX -- I
|
|
|
|
* am not sure of this.
|
|
|
|
*/
|
|
|
|
|
|
|
|
temp = lcons(tlist_other_var, NIL);
|
|
|
|
t_list = nconc(t_list, temp);
|
|
|
|
}
|
|
|
|
}
|
1998-09-01 05:29:17 +02:00
|
|
|
return t_list;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|