head	1.18;
access;
symbols
	release_4_2:1.18
	aix_ok:1.18
	Version_2_1:1.10
	C_Demo_1:1.7
	Retrieve_x_qual:1.5
	Retrieve_x_all:1.4
	Retrieve_x_1:1.3;
locks; strict;
comment	@ * @;


1.18
date	93.09.19.05.10.10;	author aoki;	state Exp;
branches;
next	1.17;

1.17
date	92.11.23.22.38.29;	author joey;	state Exp;
branches;
next	1.16;

1.16
date	92.07.23.15.33.07;	author joey;	state Exp;
branches;
next	1.15;

1.15
date	92.03.31.23.13.14;	author mer;	state Exp;
branches;
next	1.14;

1.14
date	91.11.17.20.39.50;	author mer;	state Exp;
branches;
next	1.13;

1.13
date	91.11.15.16.27.13;	author hong;	state Exp;
branches;
next	1.12;

1.12
date	91.11.02.21.42.29;	author hong;	state Exp;
branches;
next	1.11;

1.11
date	91.05.29.23.11.11;	author hong;	state Exp;
branches;
next	1.10;

1.10
date	90.09.25.16.35.55;	author kemnitz;	state Exp;
branches;
next	1.9;

1.9
date	90.05.30.18.56.46;	author cimarron;	state Exp;
branches;
next	1.8;

1.8
date	89.09.29.14.43.52;	author hong;	state Exp;
branches;
next	1.7;

1.7
date	89.09.05.17.17.29;	author mao;	state C_Demo_1;
branches;
next	1.6;

1.6
date	89.08.23.16.02.42;	author ong;	state Exp;
branches;
next	1.5;

1.5
date	89.08.04.14.27.21;	author goh;	state Exp;
branches;
next	1.4;

1.4
date	89.08.04.13.23.21;	author goh;	state Exp;
branches;
next	1.3;

1.3
date	89.08.01.14.40.02;	author goh;	state Exp;
branches;
next	1.2;

1.2
date	89.07.21.10.29.21;	author ong;	state Exp;
branches;
next	1.1;

1.1
date	89.07.10.15.16.26;	author ong;	state Exp;
branches;
next	;


desc
@stuff for join relation
@


1.18
log
@existential clauses 'OR'ed together generated bushy trees.
not good.  now they only do so if you turn on BushyPlanFlag.
@
text
@
/*     
 *      FILE
 *     	joinrels
 *     
 *      DESCRIPTION
 *     	Routines to determine which relations should be joined
 *     
 */

/*  RcsId("$Header: /home2/aoki/postgres/src/backend/planner/path/RCS/joinrels.c,v 1.17 1992/11/23 22:38:29 joey Exp aoki $");  */

/*     
 *      EXPORTS
 *     		find-join-rels
 */

#include "nodes/pg_lisp.h"
#include "nodes/relation.h"
#include "nodes/relation.a.h"

#include "planner/internal.h"
#include "planner/joinrels.h"
#include "planner/joininfo.h"
#include "planner/relnode.h"

/*    
 *    	find-join-rels
 *    
 *    	Find all possible joins for each of the outer join relations in
 *    	'outer-rels'.  A rel node is created for each possible join relation,
 *    	and the resulting list of nodes is returned.  If at all possible, only
 *    	those relations for which join clauses exist are considered.  If none
 *    	of these exist for a given relation, all remaining possibilities are
 *    	considered.
 *    
 *    	'outer-rels' is the list of rel nodes
 *    
 *    	Returns a list of rel nodes corresponding to the new join relations.
 *    
 */

/*  .. find-join-paths    */

LispValue
find_join_rels(outer_rels)
     LispValue outer_rels ;
{
    Rel outer_rel;
    LispValue temp = LispNil;
    LispValue t_list = LispNil;
    LispValue i = LispNil;

    foreach(i,outer_rels) {
	outer_rel = (Rel)CAR(i);
	if(!(temp = find_clause_joins(outer_rel,get_joininfo(outer_rel))))
	  if (BushyPlanFlag)
	      temp = find_clauseless_joins(outer_rel,outer_rels);
	  else
	      temp = find_clauseless_joins(outer_rel,_base_relation_list_);
	t_list = nconc(t_list,temp);
    }
    return(t_list);

}  /* function end  */

/*    
 *    	find-clause-joins
 *    
 *    	Determines whether joins can be performed between an outer relation
 *    	'outer-rel' and those relations within 'outer-rel's joininfo nodes
 *    	(i.e., relations that participate in join clauses that 'outer-rel'
 *    	participates in).  This is possible if all but one of the relations
 *    	contained within the join clauses of the joininfo node are already
 *    	contained within 'outer-rel'.
 *    
 *    	'outer-rel' is the relation entry for the outer relation
 *    	'joininfo-list' is a list of join clauses which 'outer-rel' 
 *    		participates in
 *    
 *    	Returns a list of new join relations.
 *    
 */

/*  .. find-join-rels    */

LispValue
find_clause_joins(outer_rel,joininfo_list)
     Rel outer_rel;
     List joininfo_list ;
{
     LispValue temp_node = LispNil;
     LispValue t_list = LispNil;
     LispValue i = LispNil;
     
     foreach(i,joininfo_list) {
	 JInfo joininfo = (JInfo)CAR(i);
         if(!joininfo_inactive(joininfo)) {
               LispValue other_rels = get_otherrels(joininfo);
               if(!null(other_rels)) {
                  if(length(other_rels) == 1)
                     temp_node = lispCons((LispValue)init_join_rel(outer_rel,
                                                       get_rel(CAR(other_rels)),
                                                       joininfo),
                                          LispNil);
                  else if (BushyPlanFlag)
                     temp_node = lispCons((LispValue)init_join_rel(outer_rel,
                                                        get_rel(other_rels),
                                                         joininfo),
                                          LispNil);
		  else
		     temp_node = LispNil;
                t_list = nconc(t_list,temp_node);

              }
           }
       }
     return(t_list);

}  /* function end  */

/*    
 *    	find-clauseless-joins
 *    
 *    	Given an outer relation 'outer-rel' and a list of inner relations
 *    	'inner-rels', create a join relation between 'outer-rel' and each
 *    	member of 'inner-rels' that isn't already included in 'outer-rel'.
 *    
 *    	Returns a list of new join relations.
 *    
 */

/*  .. find-join-rels    */

LispValue
find_clauseless_joins(outer_rel,inner_rels)
     Rel outer_rel;
     List inner_rels ;
{
     /*  XXX was mapcan   */
     Rel inner_rel;
     LispValue t_list = LispNil;
     LispValue temp_node = LispNil;
     LispValue i = LispNil;

     foreach(i,inner_rels) {
	 inner_rel = (Rel)CAR(i);
         if(nonoverlap_rels(inner_rel,outer_rel)) {
	     temp_node = lispCons((LispValue)init_join_rel(outer_rel, 
							   inner_rel,
							   (JInfo)NULL),
				   LispNil);
	     t_list = nconc(t_list,temp_node);
	 } 
     }
     return(t_list);

}  /*  function end   */

/*    
 *    	init-join-rel
 *    
 *    	Creates and initializes a new join relation.
 *    
 *    	'outer-rel' and 'inner-rel' are relation nodes for the relations to be
 *    		joined
 *    	'joininfo' is the joininfo node(join clause) containing both
 *    		'outer-rel' and 'inner-rel', if any exists
 *    
 *    	Returns the new join relation node.
 *    
 */

/*  .. find-clause-joins, find-clauseless-joins   */

Rel
init_join_rel(outer_rel,inner_rel,joininfo)
     Rel outer_rel,inner_rel;
     JInfo joininfo ;
{
    Rel joinrel = RMakeRel();
    LispValue joinrel_joininfo_list = LispNil;
    
    /*    Create a new tlist by removing irrelevant elements from both */
    /*    tlists of the outer and inner join relations and then merging */
    /*    the results together. */

    LispValue new_outer_tlist = 
      new_join_tlist(get_targetlist(outer_rel)   /*   XXX 1-based attnos */
		      ,get_relids(inner_rel),1);
    LispValue new_inner_tlist = 
      new_join_tlist(get_targetlist  (inner_rel)    /*   XXX 1-based attnos */
		      ,get_relids(outer_rel),
		      length(new_outer_tlist) + 1);
     
     
    set_relids(joinrel, LispNil);
    set_indexed(joinrel,false);
    set_pages(joinrel, 0);
    set_tuples(joinrel,0);
    set_width(joinrel,0);
    set_targetlist(joinrel,LispNil);
    set_pathlist(joinrel,LispNil);
    set_unorderedpath(joinrel,(PathPtr)NULL);
    set_cheapestpath(joinrel,(PathPtr)NULL);
    set_pruneable(joinrel,true);
    set_classlist(joinrel,(List)NULL);
    set_ordering(joinrel,LispNil);
    set_clauseinfo(joinrel,LispNil);
    set_joininfo(joinrel,LispNil);
    set_innerjoin(joinrel,LispNil);
    set_superrels(joinrel,LispNil);
    
    set_relids(joinrel,lispCons(get_relids(outer_rel),
				lispCons(get_relids(inner_rel),
					  LispNil)));
    new_outer_tlist = nconc(new_outer_tlist,new_inner_tlist);
    set_targetlist(joinrel,new_outer_tlist);
    
    if( joininfo) {
	set_clauseinfo(joinrel,get_jinfoclauseinfo(joininfo));
	if (BushyPlanFlag) deactivate_joininfo(joininfo);
    }
    
    
    joinrel_joininfo_list = 
      new_joininfo_list(append(get_joininfo(outer_rel),get_joininfo(inner_rel)),
                        append(get_relids(outer_rel), get_relids(inner_rel)));

    set_joininfo(joinrel,joinrel_joininfo_list);

    return(joinrel);

}  /* function end  */

/*    
 *    	new-join-tlist
 *    
 *    	Builds a join relations's target list by keeping those elements that 
 *    	will be in the final target list and any other elements that are still 
 *    	needed for future joins.  For a target list entry to still be needed 
 *    	for future joins, its 'joinlist' field must not be empty after removal 
 *    	of all relids in 'other-relids'.
 *    
 *    	'tlist' is the target list of one of the join relations
 *    	'other-relids' is a list of relids contained within the other
 *    		join relation
 *    	'first-resdomno' is the resdom number to use for the first created
 *    		target list entry
 *    
 *    	Returns the new target list.
 *    
 */

/*  .. init-join-rel    */

LispValue
new_join_tlist(tlist,other_relids,first_resdomno)
     LispValue tlist,other_relids;
     int first_resdomno ;
{
    int resdomno = first_resdomno - 1;
    LispValue xtl = LispNil;
    LispValue temp_node = LispNil;
    LispValue t_list = LispNil;
    LispValue i = LispNil;
    LispValue join_list = LispNil;
    bool in_final_tlist =false;
    LispValue future_join_list = LispNil;
    

    foreach(i,tlist) {
	xtl= CAR(i);
	join_list = get_joinlist(xtl);
	in_final_tlist = null(join_list);
	if( join_list ) 
	  future_join_list = set_difference(join_list,other_relids);
	else
	  future_join_list = LispNil;
	if( in_final_tlist || future_join_list)  {
	    resdomno += 1;
	    temp_node = 
	      lispCons((LispValue)create_tl_element(get_expr(get_entry(xtl)),
					   resdomno,
					   future_join_list),
			LispNil);
	    t_list = nconc(t_list,temp_node);
	} 
    }
    return(t_list);
}

/*    
 *    	new-joininfo-list
 *    
 *    	Builds a join relation's joininfo list by checking for join clauses
 *    	which still need to used in future joins involving this relation.  A
 *    	join clause is still needed if there are still relations in the clause
 *    	not contained in the list of relations comprising this join relation.
 *    	New joininfo nodes are only created and added to
 *    	'current-joininfo-list' if a node for a particular join hasn't already
 *    	been created.
 *    
 *    	'current-joininfo-list' contains a list of those joininfo nodes that 
 *    		have already been built 
 *    	'joininfo-list' is the list of join clauses involving this relation
 *    	'join-relids' is a list of relids corresponding to the relations 
 *    		currently being joined
 *    
 *    	Returns a list of joininfo nodes, new and old.
 *    
 */

/*  .. init-join-rel    */

LispValue
new_joininfo_list(joininfo_list,join_relids)
     LispValue joininfo_list,join_relids ;
{
   LispValue current_joininfo_list = LispNil;
   LispValue new_otherrels = LispNil;
   JInfo other_joininfo = (JInfo)NULL;
   LispValue xjoininfo = LispNil;

   foreach(xjoininfo, joininfo_list) {
      JInfo joininfo = (JInfo)CAR(xjoininfo);
      new_otherrels = get_otherrels(joininfo);
      if (nonoverlap_sets(new_otherrels,join_relids)) {
         other_joininfo = joininfo_member(new_otherrels,current_joininfo_list);
         if(other_joininfo)
	 {
            set_jinfoclauseinfo(other_joininfo, LispUnion((LispValue)get_jinfoclauseinfo(joininfo), (LispValue)get_jinfoclauseinfo(other_joininfo)));
	 }
         else {
            other_joininfo = MakeJInfo(get_otherrels(joininfo),
                                        get_jinfoclauseinfo(joininfo),
                                        get_mergesortable(joininfo),
                                        get_hashjoinable(joininfo),
					false);
            current_joininfo_list = push((LispValue)other_joininfo,
					 current_joininfo_list);
         }
       }
    }
    return(current_joininfo_list);
} /* function end  */

/*
 *      add-new-joininfos
 *
 *      For each new join relation, create new joininfos that
 *      use the join relation as inner relation, and add
 *      the new joininfos to those rel nodes that still
 *      have joins with the join relation.
 *
 *      'joinrels' is a list of join relations.
 *
 *      Modifies the joininfo field of appropriate rel nodes.
 *
 */

/*  .. find-join-paths
 */
LispValue
add_new_joininfos(joinrels,outerrels)
LispValue joinrels,outerrels ;
{
    LispValue xjoinrel = LispNil;
    LispValue xrelid = LispNil;
    LispValue xrel = LispNil;
    LispValue xjoininfo = LispNil;

    foreach(xjoinrel, joinrels) {
	Rel joinrel = (Rel)CAR(xjoinrel);
        foreach(xrelid, get_relids(joinrel)) {
	    Relid relid = (Relid)CAR(xrelid);
	    Rel rel = get_rel(relid);
	    add_superrels(rel,joinrel);
	}
    }
    foreach(xjoinrel, joinrels) {
	Rel joinrel = (Rel)CAR(xjoinrel);
	foreach(xjoininfo, get_joininfo(joinrel)) {
	    JInfo joininfo = (JInfo)CAR(xjoininfo);
	    LispValue other_rels = get_otherrels(joininfo);
	    LispValue clause_info = get_jinfoclauseinfo(joininfo);
	    bool mergesortable = get_mergesortable(joininfo);
	    bool hashjoinable = get_hashjoinable(joininfo);
	    foreach(xrelid, other_rels) {
		Relid relid = (Relid)CAR(xrelid);
		Rel rel = get_rel(relid);
		List super_rels = get_superrels(rel);
		LispValue xsuper_rel = LispNil;
		JInfo new_joininfo = MakeJInfo(get_relids(joinrel),
						    clause_info,
						    mergesortable,
						    hashjoinable,
						    false);
	        set_joininfo(rel,nappend1(get_joininfo(rel), (LispValue)new_joininfo));
		foreach(xsuper_rel, super_rels) {
		    Rel super_rel = (Rel)CAR(xsuper_rel);
		    if( nonoverlap_rels(super_rel,joinrel) ) {
			LispValue new_relids = get_relids(super_rel);
			JInfo other_joininfo = 
				  joininfo_member(new_relids,
						   get_joininfo(joinrel));
			if( other_joininfo ) {
			    set_jinfoclauseinfo(other_joininfo, LispUnion(clause_info, get_jinfoclauseinfo(other_joininfo)));
			} else {
			    JInfo new_joininfo = MakeJInfo(new_relids,
								clause_info,
								mergesortable,
								hashjoinable,
								false);
			    set_joininfo(joinrel, nappend1 (get_joininfo(joinrel), (LispValue)new_joininfo));
			}
		    }
		}
	     }
	 }
    }
    foreach(xrel, outerrels)  {
	Rel rel = (Rel)CAR(xrel);
	set_superrels(rel,LispNil);
    }
}

/*
 *      final-join-rels
 *
 *      Find the join relation that includes all the original
 *      relations, i.e. the final join result.
 *
 *      'join-rel-list' is a list of join relations.
 *
 *      Returns the list of final join relations.
 *
 */

/*  .. find-join-paths
 */
LispValue
final_join_rels(join_rel_list)
LispValue join_rel_list ;
{
    LispValue xrel = LispNil;
    LispValue temp = LispNil;
    LispValue t_list = LispNil;

/*    find the relations that has no further joins, */
/*    i.e., its joininfos all have otherrels nil. */
    foreach(xrel,join_rel_list)  {
	Rel rel = (Rel)CAR(xrel);
	LispValue xjoininfo = LispNil;
	bool final = true;
	foreach (xjoininfo,get_joininfo(rel)) {
	    JInfo joininfo = (JInfo)CAR(xjoininfo);
	    if(get_otherrels(joininfo) != LispNil)  {
	       final = false;
	       break;
	    }
	}
	if(final)  {
	   temp = lispCons((LispValue)rel,LispNil);
	   t_list = nconc(t_list, temp);
	}
    }
    return(t_list);
}  /* function end */

/*
 *      add_superrels
 *
 *      add rel to the temporary property list superrels.
 *
 *      'rel' a rel node
 *      'super-rel' rel node of a join relation that includes rel
 *
 *      Modifies the superrels field of rel
 *
 */

/*  .. init-join-rel
 */
void
add_superrels(rel,super_rel)
Rel rel,super_rel ;
{
    set_superrels(rel, nappend1(get_superrels(rel), (LispValue)super_rel));
}

/*
 *      nonoverlap-rels
 *
 *      test if two join relations overlap, i.e., includes the same
 *      relation.
 *
 *      'rel1' and 'rel2' are two join relations
 *
 *      Returns non-nil if rel1 and rel2 do not overlap.
 *
 */

/*  .. add-new-joininfos
 */
bool
nonoverlap_rels(rel1,rel2)
Rel rel1,rel2 ;
{
    return(nonoverlap_sets(get_relids(rel1),get_relids(rel2)));
}

bool
nonoverlap_sets(s1,s2)
LispValue s1,s2 ;
{
    LispValue x = LispNil;

    foreach(x,s1)  {
       LispValue e = CAR(x);
       if(member(e,s2))
	  return(false);
    }
    return(true);
}

/*
 *	cleanup-joininfos
 *
 *      after a round of find-join-paths, clear the JoinInfos that
 *      have already been considered.
 *
 *      'outer-rels' is a list of rel nodes
 *
 *      Modifies JoinInfo fields.
 *
 */

/* .. add-new-joininfos
*/
void
cleanup_joininfos(outer_rels)
LispValue outer_rels;
{
    LispValue xrel = LispNil;

    foreach(xrel,outer_rels)  {
	Rel rel = (Rel)CAR(xrel);
	set_joininfo(rel,LispNil);
    }
}
@


1.17
log
@set pruneable flag to true by default
@
text
@d11 1
a11 1
/*  RcsId("$Header: /var/home/hellers/pg/src/planner/path/RCS/joinrels.c,v 1.16 1992/07/23 15:33:07 joey Exp $");  */
d106 1
a106 1
                  else
d111 2
@


1.16
log
@don't assume nconc will destructively modify first arg -- what if it's nil?
@
text
@d11 1
a11 1
/*  RcsId("$Header: /private/joey/pg/src/planner/path/RCS/joinrels.c,v 1.15 1992/03/31 23:13:14 mer Exp joey $");  */
d204 1
@


1.15
log
@change accessor functions into macros
@
text
@d11 1
a11 1
/*  RcsId("$Header: /users/mer/pg/src/planner/path/RCS/joinrels.c,v 1.14 1991/11/17 20:39:50 mer Exp mer $");  */
d214 2
a215 1
    set_targetlist(joinrel,nconc(new_outer_tlist,new_inner_tlist));
@


1.14
log
@prototyping
@
text
@d11 1
a11 1
/*  RcsId("$Header: /users/mer/postgres/src/planner/path/RCS/joinrels.c,v 1.13 1991/11/15 16:27:13 hong Exp mer $");  */
d202 2
a203 2
    set_unorderedpath(joinrel,(Path)NULL);
    set_cheapestpath(joinrel,(Path)NULL);
d327 3
a329 3
            set_jinfoclauseinfo(other_joininfo,
                            LispUnion((LispValue)get_jinfoclauseinfo(joininfo),
                                   (LispValue)get_jinfoclauseinfo(other_joininfo)));
d395 1
a395 2
	        set_joininfo(rel,nappend1(get_joininfo(rel),
					  (LispValue)new_joininfo));
d404 1
a404 3
			    set_jinfoclauseinfo(other_joininfo,
				  LispUnion(clause_info, 
				         get_jinfoclauseinfo(other_joininfo)));
d411 1
a411 3
			    set_joininfo(joinrel,
					 nappend1 (get_joininfo(joinrel),
						   (LispValue)new_joininfo));
@


1.13
log
@planner prototyping
@
text
@d11 1
a11 1
/*  RcsId("$Header: RCS/joinrels.c,v 1.12 91/11/02 21:42:29 hong Exp Locker: hong $");  */
d102 1
a102 1
                     temp_node = lispCons(init_join_rel(outer_rel,
d107 1
a107 1
                     temp_node = lispCons(init_join_rel(outer_rel,
d147 3
a149 1
	     temp_node = lispCons(init_join_rel(outer_rel, inner_rel, (JInfo)NULL),
d279 1
a279 1
	      lispCons(create_tl_element(get_expr(get_entry(xtl)),
d336 2
a337 1
            current_joininfo_list = push(other_joininfo, current_joininfo_list);
d395 2
a396 1
	        set_joininfo(rel,nappend1(get_joininfo(rel), new_joininfo));
d415 2
a416 1
			      nappend1 (get_joininfo(joinrel),new_joininfo));
d465 1
a465 1
	   temp = lispCons(rel,LispNil);
d490 1
a490 1
    set_superrels(rel, nappend1(get_superrels(rel), super_rel));
@


1.12
log
@cleaned up bushy tree plan generation code.
@
text
@d11 1
a11 1
/*  RcsId("$Header: RCS/joinrels.c,v 1.11 91/05/29 23:11:11 hong Exp Locker: hong $");  */
a26 7
/* ----------------
 *	node creator declarations
 * ----------------
 */
extern JInfo RMakeJInfo();
extern Rel RMakeRel();

d49 1
a49 1
    LispValue outer_rel = LispNil;
d55 1
a55 1
	outer_rel = CAR(i);
d89 2
a90 1
     LispValue outer_rel,joininfo_list ;
d135 2
a136 1
     LispValue outer_rel,inner_rels ;
d139 1
a139 1
     LispValue inner_rel = LispNil;
a142 1
     bool nonoverlap_rels();
d145 1
a145 1
	 inner_rel = CAR(i);
d147 1
a147 1
	     temp_node = lispCons(init_join_rel(outer_rel, inner_rel, LispNil),
a317 1
   bool nonoverlap_sets();
d325 3
a327 3
            set_clauseinfo(other_joininfo,
                            LispUnion(get_jinfoclauseinfo(joininfo),
                                   get_jinfoclauseinfo(other_joininfo)));
a364 2
    bool nonoverlap_rels();
    void add_superrels();
d367 1
a367 1
	LispValue joinrel = CAR(xjoinrel);
d375 1
a375 1
	LispValue joinrel = CAR(xjoinrel);
d377 1
a377 1
	    LispValue joininfo = CAR(xjoininfo);
d392 1
a392 1
	        set_joininfo(rel,append1 (get_joininfo(rel),new_joininfo));
d394 1
a394 1
		    LispValue super_rel = CAR(xsuper_rel);
d411 1
a411 1
			      append1 (get_joininfo(joinrel),new_joininfo));
d419 1
a419 1
	LispValue rel = CAR(xrel);
d449 1
a449 1
	LispValue rel = CAR(xrel);
d452 2
a453 2
	foreach(xjoininfo,get_joininfo(rel)) {
	    LispValue joininfo = CAR(xjoininfo);
d483 1
a483 1
LispValue rel,super_rel ;
d485 1
a485 1
    set_superrels(rel, append1 (get_superrels(rel), super_rel));
d504 1
a504 1
LispValue rel1,rel2 ;
a505 1
    bool nonoverlap_sets();
@


1.11
log
@a minor change for my experiments
@
text
@d11 1
a11 1
/*  RcsId("$Header: RCS/joinrels.c,v 1.10 90/09/25 16:35:55 kemnitz Exp $");  */
d53 1
a53 1
find_join_rels (outer_rels)
d61 1
a61 1
    foreach (i,outer_rels) {
d63 6
a68 7
	if (!(temp = find_clause_joins (outer_rel,get_joininfo (outer_rel))))
#ifdef _xprs_
	  temp = find_clauseless_joins (outer_rel,outer_rels);
#else /* _xprs_ */
	  temp = find_clauseless_joins (outer_rel,_query_relation_list_);
#endif /* _xprs */
	t_list = nconc(t_list,temp);   /*  XXX is this right?  */
d95 1
a95 1
find_clause_joins (outer_rel,joininfo_list)
a100 3
#ifdef _xprs_
     bool joininfo_inactive();
#endif /* _xprs_ */
d104 4
a107 5
#ifdef _xprs_
         if (!joininfo_inactive (joininfo)) {
               LispValue other_rels = get_otherrels (joininfo);
               if (!null (other_rels)) {
                  if (length (other_rels) == 1)
d113 2
a114 2
                     temp_node = lispCons(init_join_rel (outer_rel,
                                                         get_rel(other_rels),
d119 3
a121 16
            }
         }
#else /* _xprs_ */
	 LispValue other_rels = get_otherrels (joininfo);
	 if ( 1 == length (other_rels) ) {
	       temp_node = lispCons(init_join_rel(outer_rel,
						  get_rel(CAR(other_rels)),
						  joininfo),
				    LispNil);
	       t_list = nconc(t_list,temp_node);
	   } 
	 else {
	     t_list = nconc(t_list,LispNil);
	 } 
#endif /* _xprs_ */
     }
d140 1
a140 1
find_clauseless_joins (outer_rel,inner_rels)
a147 1
#ifdef _xprs_
a148 1
#endif /* _xprs_ */
d152 2
a153 13
#ifdef _xprs_
         if (nonoverlap_rels (inner_rel,outer_rel)) {
#else  /* _xprs_ */
	 if ( !member(CAR(get_relids(inner_rel)),get_relids (outer_rel))) {
#endif /* _xprs_ */
	     temp_node = lispCons (init_join_rel(outer_rel,
#ifdef _xprs_
                                                 inner_rel,
#else /* _xprs_ */
						 get_rel(CAR(get_relids 
							 (inner_rel))),
#endif /* _xprs_ */
						 LispNil),
d169 1
a169 1
 *    	'joininfo' is the joininfo node (join clause) containing both
d179 1
a179 1
init_join_rel (outer_rel,inner_rel,joininfo)
a184 3
#ifdef _xprs_
    void deactivate_joininfo();
#endif /* _xprs_ */
d191 2
a192 2
      new_join_tlist (get_targetlist (outer_rel)   /*   XXX 1-based attnos */
		      ,get_relids (inner_rel),1);
d194 3
a196 3
      new_join_tlist (get_targetlist  (inner_rel)    /*   XXX 1-based attnos */
		      ,get_relids (outer_rel),
		      length (new_outer_tlist) + 1);
d199 15
a213 15
    set_relids (joinrel, LispNil);
    set_indexed (joinrel,false);
    set_pages (joinrel, 0);
    set_tuples (joinrel,0);
    set_width (joinrel,0);
    set_targetlist (joinrel,LispNil);
    set_pathlist (joinrel,LispNil);
    set_unorderedpath (joinrel,(Path)NULL);
    set_cheapestpath (joinrel,(Path)NULL);
    set_classlist (joinrel,(List)NULL);
    set_ordering (joinrel,LispNil);
    set_clauseinfo (joinrel,LispNil);
    set_joininfo (joinrel,LispNil);
    set_innerjoin (joinrel,LispNil);
    set_superrels (joinrel,LispNil);
d215 4
a218 10
#ifdef _xprs_
    set_relids (joinrel,lispCons (get_relids (outer_rel),
                                  lispCons ( get_relids (inner_rel),
                                             LispNil)));
#else /* _xprs_ */
    set_relids (joinrel,append1 (get_relids (outer_rel),
				  CAR(get_relids (inner_rel))));
#endif /* _xprs_ */

    set_targetlist (joinrel,nconc (new_outer_tlist,new_inner_tlist));
d220 3
a222 5
    if ( joininfo) {
	set_clauseinfo (joinrel,get_jinfoclauseinfo (joininfo));
#ifdef _xprs_
        deactivate_joininfo (joininfo);
#endif /* _xprs_ */
d227 2
a228 12
#ifdef _xprs_
      new_joininfo_list (append (get_joininfo (outer_rel),
                                 get_joininfo (inner_rel)),
                         append (get_relids (outer_rel),
                                 get_relids (inner_rel)));
#else /* _xprs_ */
      new_joininfo_list (new_joininfo_list(LispNil,
					   get_joininfo (outer_rel),
					   get_relids (inner_rel)),
			 get_joininfo (inner_rel),
			 get_relids (outer_rel));
#endif /* _xprs_ */
d230 1
a230 1
    set_joininfo (joinrel,joinrel_joininfo_list);
a231 4
#ifdef _xprs_
    _query_relation_list_ = lispCons (joinrel,_query_relation_list_);
#endif /* _xprs_ */
    
d258 1
a258 1
new_join_tlist (tlist,other_relids,first_resdomno)
d274 4
a277 4
	join_list = get_joinlist (xtl);
	in_final_tlist = null (join_list);
	if ( join_list ) 
	  future_join_list = set_difference (join_list,other_relids);
d280 1
a280 1
	if ( in_final_tlist || future_join_list)  {
d283 1
a283 1
	      lispCons (create_tl_element (get_expr(get_entry (xtl)),
a315 1
#ifdef _xprs_
d317 1
a317 1
new_joininfo_list (joininfo_list,join_relids)
d326 9
a334 9
   foreach (xjoininfo, joininfo_list) {
      JInfo joininfo = (JInfo)CAR (xjoininfo);
      new_otherrels = get_otherrels (joininfo);
      if ( nonoverlap_sets (new_otherrels,join_relids) ) {
         other_joininfo = joininfo_member (new_otherrels,current_joininfo_list);
         if ( other_joininfo )
            set_clauseinfo (other_joininfo,
                            LispUnion (get_jinfoclauseinfo (joininfo),
                                   get_jinfoclauseinfo (other_joininfo)));
d336 4
a339 4
            other_joininfo = MakeJInfo (get_otherrels (joininfo),
                                        get_jinfoclauseinfo (joininfo),
                                        get_mergesortable (joininfo),
                                        get_hashjoinable (joininfo),
d345 1
a345 1
    return (current_joininfo_list);
a346 9
#else /* _xprs_ */
LispValue
new_joininfo_list (current_joininfo_list,joininfo_list,join_relids)
     LispValue current_joininfo_list,joininfo_list,join_relids ;
{
    JInfo joininfo = (JInfo)NULL;
    LispValue i = LispNil;
    LispValue new_otherrels = LispNil;
    JInfo other_joininfo = (JInfo)NULL;
a347 34
    foreach (i, joininfo_list) {
	joininfo = (JInfo)CAR(i);
	new_otherrels = 
	  set_difference (get_otherrels (joininfo),join_relids);

	if ( new_otherrels ) {
	    other_joininfo = 
	      joininfo_member (new_otherrels,current_joininfo_list);
	    if (other_joininfo) {
	        set_jinfoclauseinfo (other_joininfo,
				 LispUnion(get_jinfoclauseinfo (joininfo),
					   get_jinfoclauseinfo
					              (other_joininfo)));
	     } 
	     else {
	         other_joininfo = RMakeJInfo();
	         set_otherrels (other_joininfo,new_otherrels);
	         set_jinfoclauseinfo (other_joininfo,
				      get_jinfoclauseinfo (joininfo));
	         set_mergesortable (other_joininfo,
			            get_mergesortable (joininfo));
	         set_hashjoinable (other_joininfo,
			           get_hashjoinable (joininfo));
	         current_joininfo_list = nappend1(current_joininfo_list,
					          other_joininfo);
	         current_joininfo_list = nreverse(current_joininfo_list);
	      } 
         }
    }
    return(current_joininfo_list);  /* XXX is this right  */
}  /* function end  */
#endif /* _xprs_ */

#ifdef _xprs_
d365 1
a365 1
add_new_joininfos (joinrels,outerrels)
d375 6
a380 6
    foreach (xjoinrel, joinrels) {
	LispValue joinrel = CAR (xjoinrel);
        foreach (xrelid, get_relids (joinrel)) {
	    Relid relid = (Relid)CAR (xrelid);
	    Rel rel = get_rel (relid);
	    add_superrels (rel,joinrel);
d383 12
a394 12
    foreach (xjoinrel, joinrels) {
	LispValue joinrel = CAR (xjoinrel);
	foreach (xjoininfo, get_joininfo (joinrel)) {
	    LispValue joininfo = CAR (xjoininfo);
	    LispValue other_rels = get_otherrels (joininfo);
	    LispValue clause_info = get_jinfoclauseinfo (joininfo);
	    bool mergesortable = get_mergesortable (joininfo);
	    bool hashjoinable = get_hashjoinable (joininfo);
	    foreach (xrelid, other_rels) {
		Relid relid = (Relid)CAR (xrelid);
		Rel rel = get_rel (relid);
		List super_rels = get_superrels (rel);
d396 1
a396 1
		JInfo new_joininfo = MakeJInfo (get_relids (joinrel),
d401 5
a405 5
	        set_joininfo (rel,append1 (get_joininfo (rel),new_joininfo));
		foreach (xsuper_rel, super_rels) {
		    LispValue super_rel = CAR (xsuper_rel);
		    if ( nonoverlap_rels (super_rel,joinrel) ) {
			LispValue new_relids = get_relids (super_rel);
d407 6
a412 6
				  joininfo_member (new_relids,
						   get_joininfo (joinrel));
			if ( other_joininfo ) {
			    set_jinfoclauseinfo (other_joininfo,
				  LispUnion (clause_info, 
				         get_jinfoclauseinfo (other_joininfo)));
d414 1
a414 1
			    JInfo new_joininfo = MakeJInfo (new_relids,
d419 2
a420 2
			    set_joininfo (joinrel,
			      append1 (get_joininfo (joinrel),new_joininfo));
d427 3
a429 3
    foreach (xrel, outerrels)  {
	LispValue rel = CAR (xrel);
	set_superrels (rel,LispNil);
d448 1
a448 1
final_join_rels (join_rel_list)
d457 2
a458 2
    foreach (xrel,join_rel_list)  {
	LispValue rel = CAR (xrel);
d461 3
a463 3
	foreach (xjoininfo,get_joininfo (rel)) {
	    LispValue joininfo = CAR (xjoininfo);
	    if (get_otherrels (joininfo) != LispNil)  {
d468 3
a470 3
	if (final)  {
	   temp = lispCons (rel,LispNil);
	   t_list = nconc (t_list, temp);
d473 1
a473 1
    return (t_list);
d491 1
a491 1
add_superrels (rel,super_rel)
d494 1
a494 1
    set_superrels (rel, append1 (get_superrels (rel), super_rel));
d512 1
a512 1
nonoverlap_rels (rel1,rel2)
d516 1
a516 1
    return (nonoverlap_sets (get_relids (rel1),get_relids (rel2)));
d520 1
a520 1
nonoverlap_sets (s1,s2)
d525 1
a525 1
    foreach (x,s1)  {
d527 2
a528 2
       if (member (e,s2))
	  return (false);
d530 1
a530 1
    return (true);
d548 1
a548 1
cleanup_joininfos (outer_rels)
d553 1
a553 1
    foreach (xrel,outer_rels)  {
d555 1
a555 1
	set_joininfo (rel,LispNil);
a557 16

void
deactivate_joininfo (joininfo)
JInfo joininfo;
{
    set_inactive (joininfo, true);
}

bool
joininfo_inactive (joininfo)
JInfo joininfo;
{
    bool get_inactive();
    return (get_inactive (joininfo));
}
#endif /* _xprs_ */
@


1.10
log
@Updating from revision 1.9 to revision 1.11
@
text
@d11 1
a11 1
/*  RcsId("$Header: RCS/joinrels.c,v 1.11 90/08/14 11:10:00 cimarron Exp $");  */
d334 2
@


1.9
log
@CreateNode(Foo) --> RMakeFoo() change
@
text
@d11 1
a11 1
/*  RcsId("$Header: RCS/joinrels.c,v 1.8 89/09/29 14:43:52 hong Exp $");  */
d18 4
a21 1
#include "pg_lisp.h"
a22 2
#include "relation.h"
#include "relation.a.h"
a331 1
	resdomno += 1;
d335 1
d420 2
a421 4
	} 
	
	if (other_joininfo) {
	    set_jinfoclauseinfo (other_joininfo,
d425 15
a439 15
	} 
	else {
	    other_joininfo = RMakeJInfo();

	    set_otherrels (other_joininfo,new_otherrels);
	    set_jinfoclauseinfo (other_joininfo,
				 get_jinfoclauseinfo (joininfo));
	    set_mergesortable (other_joininfo,
			       get_mergesortable (joininfo));
	    set_hashjoinable (other_joininfo,
			      get_hashjoinable (joininfo));
	    current_joininfo_list = nappend1(current_joininfo_list,
					     other_joininfo);
	    current_joininfo_list = nreverse(current_joininfo_list);
	} 
@


1.8
log
@added in bushy tree stuffs
@
text
@d11 1
a11 1
/*  RcsId("$Header: RCS/joinrels.c,v 1.7 89/09/05 17:17:29 mao C_Demo_1 Locker: hong $");  */
d26 6
d213 1
a213 1
    Rel joinrel = CreateNode (Rel);
a230 2
    joinrel->printFunc = PrintRel;
    joinrel->equalFunc = EqualRel;
d428 1
a428 3
	    other_joininfo = CreateNode (JInfo);
	    other_joininfo->printFunc = PrintJInfo;
	    other_joininfo->equalFunc = EqualJInfo;
@


1.7
log
@Working version of C-only demo
@
text
@d11 1
a11 1
/*  RcsId("$Header: RCS/joinrels.c,v 1.6 89/08/23 16:02:42 ong Exp Locker: ong $");  */
d24 1
d56 4
a59 3
	if (find_clause_joins (outer_rel,get_joininfo (outer_rel)))
	  temp = find_clause_joins (outer_rel,get_joininfo (outer_rel));
	else
d61 1
a91 1
     LispValue joininfo = LispNil;
d95 3
a97 1
     LispValue other_rels = LispNil;
d100 21
a120 2
	 joininfo = CAR(i);
	 other_rels = get_otherrels (joininfo);
d131 1
d159 3
d165 3
d169 1
d171 3
d176 1
d209 3
d242 1
d244 5
d251 2
d257 3
d264 6
d275 2
d278 4
d365 1
d367 32
d442 1
d444 227
@


1.6
log
@planner supports all but rules and mergesort
@
text
@d11 1
a11 1
/*  RcsId("$Header: joinrels.c,v 1.5 89/08/04 14:27:21 ong Locked $");  */
@


1.5
log
@reorganised header files
@
text
@d11 1
a11 1
/*  RcsId("$Header: joinrels.c,v 1.4 89/08/04 13:23:21 goh Locked $");  */
d48 4
a51 12
     LispValue outer_rel = LispNil;
     LispValue temp = LispNil;
     LispValue t_list = LispNil;
     
     foreach (outer_rel,outer_rels) {
	  if (find_clause_joins (outer_rel,get_joininfo (outer_rel)))
	    temp = find_clause_joins (outer_rel,get_joininfo (outer_rel));
	  else
	    temp = find_clauseless_joins (outer_rel,_query_relation_list_);
	  t_list = nconc(t_list,temp);   /*  XXX is this right?  */
     }
     return(t_list);
d53 10
d87 1
a87 1
LispValue outer_rel,joininfo_list ;
d89 1
a89 2
     /*  XXX  was mapcan   */
     LispValue joininfo;
d92 2
d95 4
a98 3
     foreach(joininfo,joininfo_list) {
	  LispValue other_rels = get_otherrels (joininfo);
	  if ( 1 == length (other_rels) ) {
d104 4
a107 4
	  } 
	  else {
	       t_list = nconc(t_list,LispNil);
	  } 
d134 1
d136 10
a145 12
     foreach(inner_rel,inner_rels) {
	  if ( !member(get_relid(inner_rel),get_relids (outer_rel))) {
	       temp_node = lispCons (init_join_rel(outer_rel,
						   get_rel(get_relid 
							   (inner_rel)),
						   LispNil),
				     LispNil);
	       t_list = nconc(t_list,temp_node);
	  } 
	  else {
	       t_list = nconc(t_list,LispNil);
	  } 
d169 2
a170 1
     LispValue outer_rel,inner_rel,joininfo ;
d172 6
a177 2
     Rel joinrel = CreateNode (Rel);
     LispValue joinrel_joininfo_list;
d179 44
a222 3
	/*    Create a new tlist by removing irrelevant elements from both */
	/*    tlists of the outer and inner join relations and then merging */
	/*    the results together. */
a223 27
     LispValue new_outer_tlist = 
       new_join_tlist (get_targetlist (outer_rel)	    /*   XXX 1-based attnos */
	               ,get_relids (inner_rel),1);
     LispValue new_inner_tlist = 
       new_join_tlist (get_targetlist  (inner_rel)    /*   XXX 1-based attnos */
		       ,get_relids (outer_rel),
		       length (new_outer_tlist) - 1);

     set_relids (joinrel,nappend1 (get_relids (outer_rel),
				  get_relid (inner_rel)));
     set_targetlist (joinrel,nconc (new_outer_tlist,new_inner_tlist));

     if ( joininfo) {
	  set_clauseinfo (joinrel,get_clauseinfo (joininfo));
     };

     /* XXX - let form, maybe incorrect */
     joinrel_joininfo_list = 
       new_joininfo_list (new_joininfo_list(LispNil,
					    get_joininfo (outer_rel),
					    get_relids (inner_rel)),
			  get_joininfo (inner_rel),
			  get_relids (outer_rel));
     set_joininfo (joinrel,joinrel_joininfo_list);

     return(joinrel);

d249 2
a250 1
     LispValue tlist,other_relids,first_resdomno ;
d252 9
a260 5
     /*  XXX was mapcan  */
	LispValue resdomno = first_resdomno - 1;
	LispValue xtl = LispNil;
	LispValue temp_node = LispNil;
	LispValue t_list = LispNil;
d262 14
a275 5
	LispValue join_list = get_joinlist (xtl);
	bool in_final_tlist = null (join_list);
	LispValue future_join_list = LispNil;
	if ( join_list ) {
	     future_join_list = set_difference (join_list,other_relids);
d277 3
a279 15
	foreach(xtl,tlist) {
	     if ( in_final_tlist || future_join_list)  {
		  temp_node = 
		    lispCons (create_tl_element (get_expr(get_entry (xtl)),
						 resdomno++,
						 future_join_list),
			      LispNil);
		  t_list = nconc(t_list,temp_node);
	     } 
	     else {
		  t_list = nconc(t_list,LispNil);
	     } 
	}
	return(t_list);
   }
d308 4
a311 9
     LispValue joininfo = LispNil;
	foreach (joininfo, joininfo_list) {
	     LispValue new_otherrels = 
	       set_difference (get_otherrels (joininfo),join_relids);
	     JInfo other_joininfo;
	     if ( new_otherrels ) {
		  other_joininfo = 
		    joininfo_member (new_otherrels,current_joininfo_list);
	     } 
d313 34
a346 17
	     if (other_joininfo) {
		  set_clauseinfo (other_joininfo,
				   LispUnion(get_clauseinfo (joininfo),
					  get_clauseinfo (other_joininfo)));
	     } 
	     else {
		  other_joininfo = CreateNode (JInfo);
		  set_otherrels (other_joininfo,new_otherrels);
		  set_clauseinfo (other_joininfo,get_clauseinfo (joininfo));
		  set_mergesortable (other_joininfo,
				     get_mergesortable (joininfo));
		  set_hashjoinable (other_joininfo,
				    get_hashjoinable (joininfo));
		  push (other_joininfo,current_joininfo_list);
	     } 
	}
	return(current_joininfo_list);  /* XXX is this right  */
@


1.4
log
@checkin for retrieve (x.all)
@
text
@d11 1
a11 1
/*  RcsId("$Header: joinrels.c,v 1.3 89/08/01 14:40:02 goh Locked $");  */
d19 1
a19 1
#include "internal.h"
d22 2
a23 2
#include "joinrels.h"
#include "joininfo.h"
@


1.3
log
@retrieve (x=1) checkin
@
text
@d11 1
a11 1
/*  RcsId("$Header: joinrels.c,v 1.2 89/07/21 10:29:21 ong Locked $");  */
@


1.2
log
@Phase II checkin.  Has some externs that need to go.
@
text
@d11 1
a11 1
/*  RcsId("$Header: joinrels.c,v 1.1 89/07/10 15:16:26 ong Locked $");  */
a25 10
/*  These are functions defined in relation.l but not in relation.c.
 *  They need to either be converted, or replaced by their 
 *  equivalent new functions.
 */
extern LispValue get_other_rels();  /*
				     * The OtherRels field is a list of 
				     * relids used in the join clause
				     */
extern LispValue get_join_list();    /* returns a list of relids to which
				      
d53 2
a54 2
	  if (find_clause_joins (outer_rel,get_join_info (outer_rel)))
	    temp = find_clause_joins (outer_rel,get_join_info (outer_rel));
d93 1
a93 1
	  LispValue other_rels = get_other_rels (joininfo);
d95 4
a98 3
	       temp_node = list (init_join_rel(outer_rel,
					       get_rel(car (other_rels)),
					       joininfo));
d133 5
a137 3
	       temp_node = list (init_join_rel(outer_rel,
					       get_rel(get_relid (inner_rel)),
					       LispNil));
d176 1
a176 1
       new_join_tlist (get_tlist (outer_rel)	    /*   XXX 1-based attnos */
d179 1
a179 1
       new_join_tlist (get_tlist (inner_rel)    /*   XXX 1-based attnos */
d183 1
a183 1
     set_relids (joinrel,append1 (get_relids (outer_rel),
d185 1
a185 1
     set_tlist (joinrel,nconc (new_outer_tlist,new_inner_tlist));
d188 1
a188 1
	  set_clause_info (joinrel,get_clause_info (joininfo));
d194 1
a194 1
					    get_join_info (outer_rel),
d196 1
a196 1
			  get_join_info (inner_rel),
d198 1
a198 1
     set_join_info (joinrel,joinrel_joininfo_list);
d235 1
a235 1
	LispValue join_list = get_join_list (xtl);
d242 1
a242 1
	     if ( or (in_final_tlist,future_join_list) ) {
d244 4
a247 3
		    list (create_tl_element (tl_expr(get_tlelement (xtl)),
					     incf (resdomno),
					     future_join_list));
d287 1
a287 1
	       set_difference (get_other_rels (joininfo),join_relids);
d295 3
a297 3
		  set_clause_info (other_joininfo,
				   Lispunion(get_clause_info (joininfo),
					  get_clause_info (other_joininfo)));
d301 2
a302 2
		  set_other_rels (other_joininfo,new_otherrels);
		  set_clause_info (other_joininfo,get_clause_info (joininfo));
@


1.1
log
@Initial revision
@
text
@d11 1
a11 1
/*  RcsId("$Header: joinrels.c,v 1.1 89/04/27 21:04:23 ong Locked $");  */
d18 1
d20 4
a23 1
#include "pg_lisp.h"
a24 5
extern LispValue find_clause_joins();
extern LispValue find_clauseless_joins();
extern LispValue init_join_rel();
extern LispValue new_join_tlist();
extern LispValue new_joininfo_list();
d26 10
a35 1

d63 4
a66 2
	  temp = find_clause_joins (outer_rel,get_join_info (outer_rel))
	    || find_clauseless_joins (outer_rel,_query_relation_list_);
d98 1
a98 1
     LispValue joininfo = LispNil ;
d171 1
a171 1
LispValue
d175 1
a175 1
     LispValue joinrel = create_node ("Rel");
d243 1
a243 1
	LispValue in_final_tlist = null (join_list);
d294 1
a294 1
	     LispValue other_joininfo = LispNil;
d306 1
a306 1
		  other_joininfo = create_node ("JoinInfo");
@
