You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2012/06/08 06:47:19 UTC

svn commit: r1347879 - in /db/torque/torque4/trunk: torque-runtime/src/main/java/org/apache/torque/criteria/ torque-runtime/src/main/java/org/apache/torque/sql/ torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ torque-runtime/src/main/j...

Author: tfischer
Date: Fri Jun  8 04:47:18 2012
New Revision: 1347879

URL: http://svn.apache.org/viewvc?rev=1347879&view=rev
Log:
TORQUE-7: allow composite join conditions

Added:
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/PreparedStatementPart.java
      - copied, changed from r1346320, db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/PreparedStatementPart.java
Removed:
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/PreparedStatementPart.java
Modified:
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/FromElement.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Join.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/WhereClauseExpression.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectOrColumnPsPartBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectPsPartBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CurrentDateTimePsPartBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CustomBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/InBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/LikeBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/NullValueBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/StandardBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/VerbatimSqlConditionBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/WhereClausePsPartBuilder.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java
    db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/CriteriaTest.java
    db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/JoinTest.java
    db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/QueryTest.java
    db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java
    db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/CriteriaTest.java
    db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/JoinTest.java
    db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/oid/IDBrokerTest.java

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java Fri Jun  8 04:47:18 2012
@@ -451,7 +451,7 @@ public class Criteria
      */
     public Criteria addJoin(Column left, Column right, JoinType joinType)
     {
-        joins.add(new Join(left, right, joinType));
+        joins.add(new Join(left, right, Criteria.EQUAL, joinType));
 
         return this;
     }
@@ -469,10 +469,10 @@ public class Criteria
      *     Criteria.LEFT_JOIN);
      * </code>
      *
-     * @param left A String with the left side of the join.
+     * @param left A String with the left side of the join condition.
+     * @param right A String with the right side of the join condition.
      * @param comparison the comparison operator, not null.
      *        The operator CUSTOM is not supported.
-     * @param right A String with the right side of the join.
      * @param joinType The operator used for the join. Must be one of null,
      *        Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
      *
@@ -480,11 +480,91 @@ public class Criteria
      */
     public Criteria addJoin(
             Column left,
-            SqlEnum comparison,
             Column right,
+            SqlEnum comparison,
+            JoinType joinType)
+    {
+        joins.add(new Join(left, right, comparison, joinType));
+
+        return this;
+    }
+
+    /**
+     * Adds a join to the criteria, E.g. to create the condition
+     * <p>
+     * PROJECT LEFT JOIN FOO ON PROJECT.PROJECT_ID=FOO.PROJECT_ID
+     * <p> use <p>
+     * <code>
+     * criteria.addJoin(
+     *     ProjectPeer.TABLE_NAME,
+     *     FooPeer.TABLE_NAME,
+     *     new Criterion(ProjectPeer.PROJECT_ID,
+     *         FooPeer.PROJECT_ID,
+     *         Criteria.NOT_EQUAL)
+     *     Criteria.LEFT_JOIN);
+     * </code>
+     *
+     * @param leftTable the left table of the join, or null to determine
+     *        the left table from the join condition.
+     * @param rightTable the left table of the join, or null to determine
+     *        the left table from the join condition.
+     * @param joinCondition the join condition, not null.
+     * @param joinType The operator used for the join. Must be one of null,
+     *        Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
+     *
+     * @return A modified Criteria object.
+     */
+    public Criteria addJoin(
+            String leftTable,
+            String rightTable,
+            Criterion joinCondition,
+            JoinType joinType)
+    {
+        joins.add(new Join(
+                new PreparedStatementPart(leftTable),
+                new PreparedStatementPart(rightTable),
+                joinCondition,
+                joinType));
+
+        return this;
+    }
+
+    /**
+     * Adds a join to the criteria, E.g. to create the condition
+     * <p>
+     * PROJECT LEFT JOIN FOO ON PROJECT.PROJECT_ID=FOO.PROJECT_ID
+     * <p> use <p>
+     * <code>
+     * criteria.addJoin(
+     *     new PreparedStatementPart(ProjectPeer.TABLE_NAME),
+     *     new PreparedStatementPart(FooPeer.TABLE_NAME),
+     *     new Criterion(ProjectPeer.PROJECT_ID,
+     *         FooPeer.PROJECT_ID,
+     *         Criteria.NOT_EQUAL)
+     *     Criteria.LEFT_JOIN);
+     * </code>
+     *
+     * @param leftTable the left table of the join, might contain an alias name,
+     *        or null to be determined from the join clause.
+     * @param rightTable the right table of the join, might contain an alias
+     *        name, or null to be determined from the join clause.
+     * @param joinCondition the join condition, not null.
+     * @param joinType The operator used for the join. Must be one of null,
+     *        Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
+     *
+     * @return A modified Criteria object.
+     */
+    public Criteria addJoin(
+            PreparedStatementPart leftTable,
+            PreparedStatementPart rightTable,
+            Criterion joinCondition,
             JoinType joinType)
     {
-        joins.add(new Join(left, comparison, right, joinType));
+        joins.add(new Join(
+                leftTable,
+                rightTable,
+                joinCondition,
+                joinType));
 
         return this;
     }

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/FromElement.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/FromElement.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/FromElement.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/FromElement.java Fri Jun  8 04:47:18 2012
@@ -121,6 +121,30 @@ public class FromElement
         }
     }
 
+    /**
+     * Constructor.
+     *
+     * @param fromExpression the expression to add to the from clause,
+     *        e.g. a simple table name or a table name with an alias,
+     *        e.g. <br />
+     *        table_1<br />
+     *        table_1 alias_for_table_1
+     * @param joinType the type of the join, e.g. JoinType.LEFT_JOIN,
+     *        or null if no explicit join is wanted
+     * @param joinCondition the join condition,
+     *        e.g. table_a.id = table_b.a_id, not null.
+     */
+    public FromElement(
+            String fromExpression,
+            JoinType joinType,
+            PreparedStatementPart joinCondition)
+    {
+        this(fromExpression,
+                joinType,
+                joinCondition.getSql().toString(),
+                joinCondition.getPreparedStatementReplacements());
+    }
+
 
     /**
      * Returns the join condition.

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Join.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Join.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Join.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Join.java Fri Jun  8 04:47:18 2012
@@ -30,69 +30,43 @@ import org.apache.torque.Column;
  * <pre>
  * table_a LEFT JOIN table_b ON table_a.id = table_b.a_id
  * </pre>
- * The class is immutable.
  */
 public class Join implements Serializable
 {
     /** Version id for serializing. */
     private static final long serialVersionUID = 1L;
 
-    /** The left column of the join condition, not null. */
-    private Column leftColumn = null;
+    /** The join condition, not null. */
+    private Criterion joinCondition = null;
 
-    /** The comparison operator. The operator CUSTOM is not supported. */
-    private SqlEnum comparison = SqlEnum.EQUAL;
-
-    /** The right column of the join condition, not null. */
-    private Column rightColumn = null;
+    /**
+     * The left table of the join,
+     * or null to be determined from join condition.
+     */
+    private PreparedStatementPart leftTable = null;
 
     /**
+     * The right table of the join,
+     * or null to be determined from join condition.
+     */
+    private PreparedStatementPart rightTable = null;
+    /**
      * The type of the join (LEFT JOIN, ...),
      * or null for an implicit inner join.
      */
     private JoinType joinType = null;
 
     /**
-     * Constructor.
+     * Constructor with the comparison operator.
      *
      * @param leftColumn the left column of the join condition;
      *        might contain an alias name, not null.
      * @param rightColumn the right column of the join condition
      *        might contain an alias name, not null.
-     * @param joinType the type of the join. Valid join types are
-     *        null (adding the join condition to the where clause),
-     *        SqlEnum.LEFT_JOIN, SqlEnum.RIGHT_JOIN, and SqlEnum.INNER_JOIN
-     */
-    public Join(
-            final Column leftColumn,
-            final Column rightColumn,
-            final JoinType joinType)
-    {
-        if (leftColumn == null)
-        {
-            throw new NullPointerException("leftColumn is null");
-        }
-        if (rightColumn == null)
-        {
-            throw new NullPointerException("rightColumn is null");
-        }
-        this.leftColumn = leftColumn;
-        this.rightColumn = rightColumn;
-        this.joinType = joinType;
-    }
-
-    /**
-     * Constructor with the comparison operator.
-     *
-     * @param leftColumn the left column of the join condition;
-     *        might contain an alias name, not null.
      * @param comparison the comparison, not null.
      *        The operator CUSTOM is not supported.
-     * @param rightColumn the right column of the join condition
-     *        might contain an alias name, not null.
-     * @param joinType the type of the join. Valid join types are
-     *        null (adding the join condition to the where clause),
-     *        SqlEnum.LEFT_JOIN, SqlEnum.RIGHT_JOIN, and SqlEnum.INNER_JOIN
+     * @param joinType the type of the join, or null
+     *        (adding the join condition to the where clause).
      *
      * @throws NullPointerException if leftColumn, comparison or rightColumn
      *         are null.
@@ -100,8 +74,8 @@ public class Join implements Serializabl
      */
     public Join(
             final Column leftColumn,
-            final SqlEnum comparison,
             final Column rightColumn,
+            final SqlEnum comparison,
             final JoinType joinType)
     {
         if (leftColumn == null)
@@ -121,9 +95,34 @@ public class Join implements Serializabl
             throw new IllegalArgumentException(
                     "The comparison SqlEnum.CUSTOM is not supported for Joins.");
         }
-        this.leftColumn = leftColumn;
-        this.comparison = comparison;
-        this.rightColumn = rightColumn;
+        this.joinCondition = new Criterion(leftColumn, rightColumn, comparison);
+        this.joinType = joinType;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param leftTable the left table of the join, might contain an alias name,
+     *        or null to be determined from the join clause.
+     * @param rightTable the right table of the join, might contain an alias
+     *        name, or null to be determined from the join clause.
+     * @param joinType the join condition, not null.
+     * @param joinType the type of the join, or null
+     *        (adding the join condition to the where clause).
+     */
+    public Join(
+            final PreparedStatementPart leftTable,
+            final PreparedStatementPart rightTable,
+            final Criterion joinCondition,
+            final JoinType joinType)
+    {
+        if (joinCondition == null)
+        {
+            throw new NullPointerException("joinCondition is null");
+        }
+        this.leftTable = leftTable;
+        this.rightTable = rightTable;
+        this.joinCondition = joinCondition;
         this.joinType = joinType;
     }
 
@@ -131,55 +130,47 @@ public class Join implements Serializabl
      * @return the type of the join, i.e. SqlEnum.LEFT_JOIN, ...,
      *         or null for adding the join condition to the where Clause
      */
-    public final JoinType getJoinType()
+    public final Criterion getJoinCondition()
     {
-        return joinType;
+        return joinCondition;
     }
 
     /**
-     * @return the left column of the join condition.
+     * @return the type of the join, i.e. SqlEnum.LEFT_JOIN, ...,
+     *         or null for adding the join condition to the where Clause
      */
-    public final Column getLeftColumn()
+    public final JoinType getJoinType()
     {
-        return leftColumn;
+        return joinType;
     }
 
     /**
-     * @return the comaprsion operator between leftColumn and rightColumn,
+     * @return the left table of the join condition.
      */
-    public final SqlEnum getComparison()
+    public final PreparedStatementPart getLeftTable()
     {
-        return comparison;
+        return leftTable;
     }
 
     /**
-     * @return the right column of the join condition.
+     * @return the right table of the join condition.
      */
-    public final Column getRightColumn()
+    public final PreparedStatementPart getRightTable()
     {
-        return rightColumn;
+        return rightTable;
     }
 
     /**
-     * returns a String representation of the class,
-     * mainly for debuggung purposes.
+     * Returns a String representation of the class,
+     * mainly for debugging purposes.
      *
      * @return a String representation of the class
      */
     public String toString()
     {
-        StringBuffer result = new StringBuffer();
-        if (joinType != null)
-        {
-            result.append(joinType)
-                    .append(" : ");
-        }
-        result.append(leftColumn.getSqlExpression())
-                .append(comparison)
-                .append(rightColumn.getSqlExpression())
-                .append(" (ignoreCase not considered)");
 
-        return result.toString();
+        return joinType + "(" + leftTable + ", " + rightTable + "): "
+            + joinCondition.toString();
     }
 
     /**
@@ -199,12 +190,10 @@ public class Join implements Serializabl
         }
 
         Join join = (Join) obj;
-        return new EqualsBuilder().append(
-                leftColumn.getSqlExpression(),
-                join.leftColumn.getSqlExpression())
-            .append(
-                rightColumn.getSqlExpression(),
-                join.rightColumn.getSqlExpression())
+        return new EqualsBuilder()
+            .append(leftTable, join.leftTable)
+            .append(rightTable, join.rightTable)
+            .append(joinCondition, join.joinCondition)
             .append(joinType, join.getJoinType())
             .isEquals();
     }
@@ -216,10 +205,11 @@ public class Join implements Serializabl
      */
     public int hashCode()
     {
-        return new HashCodeBuilder().append(leftColumn.getSqlExpression())
-            .append(rightColumn.getSqlExpression())
+        return new HashCodeBuilder()
+            .append(leftTable)
+            .append(rightTable)
+            .append(joinCondition)
             .append(joinType)
             .toHashCode();
     }
-
 }

Copied: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/PreparedStatementPart.java (from r1346320, db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/PreparedStatementPart.java)
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/PreparedStatementPart.java?p2=db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/PreparedStatementPart.java&p1=db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/PreparedStatementPart.java&r1=1346320&r2=1347879&rev=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/PreparedStatementPart.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/PreparedStatementPart.java Fri Jun  8 04:47:18 2012
@@ -1,4 +1,4 @@
-package org.apache.torque.sql;
+package org.apache.torque.criteria;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -84,6 +84,16 @@ public class PreparedStatementPart
     }
 
     /**
+     * Returns the SQL of the part as String.
+     *
+     * @return the SQL, not null.
+     */
+    public String getSqlAsString()
+    {
+        return sql.toString();
+    }
+
+    /**
      * Returns the list of prepared statement replacements.
      *
      * @return the modifiable list of prepared statement replacements, not null.
@@ -108,6 +118,19 @@ public class PreparedStatementPart
         return this;
     }
 
+    /**
+     * Appends a SqlEnum to this part.
+     *
+     * @param toAppend the part to append, not null.
+     *
+     * @return this PreparedStatementPart (with toAppend appended).
+     */
+    public PreparedStatementPart append(SqlEnum toAppend)
+    {
+        sql.append(toAppend);
+        return this;
+    }
+
     @Override
     public int hashCode()
     {

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,14 +21,13 @@ package org.apache.torque.sql;
 
 import java.util.List;
 
-import org.apache.torque.Column;
-import org.apache.torque.Database;
 import org.apache.torque.TorqueException;
 import org.apache.torque.criteria.CriteriaInterface;
+import org.apache.torque.criteria.Criterion;
 import org.apache.torque.criteria.FromElement;
 import org.apache.torque.criteria.Join;
 import org.apache.torque.criteria.JoinType;
-import org.apache.torque.criteria.SqlEnum;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.util.UniqueList;
 
 /**
@@ -54,13 +53,12 @@ public final class JoinBuilder
     /**
      * Adds the Joins from the criteria to the query.
      *
-     * @param database the database for which the query should be built.
-     * @param criteria the criteria from which the Joins are taken
-     * @param query the query to which the Joins should be added
+     * @param criteria the criteria from which the Joins are taken.
+     * @param query the query to which the Joins should be added.
+     *
      * @throws TorqueException if the Joins can not be processed
      */
     public static void processJoins(
-                final Database database,
                 final CriteriaInterface<?> criteria,
                 final Query query)
             throws TorqueException
@@ -78,10 +76,6 @@ public final class JoinBuilder
         for (int i = 0; i < criteriaJoins.size(); i++)
         {
             Join join = criteriaJoins.get(i);
-            Column leftColumn = join.getLeftColumn();
-            SqlEnum comparison = join.getComparison();
-            Column rightColumn = join.getRightColumn();
-
             // Check the join type and add the join to the
             // appropriate places in the query
             JoinType joinType  = join.getJoinType();
@@ -90,34 +84,62 @@ public final class JoinBuilder
             {
                 // Do not treat join as explicit join, but add
                 // the join condition to the where clauses
-                SqlBuilder.addTableToFromClause(
-                        leftColumn,
-                        database,
-                        criteria,
-                        query);
-                SqlBuilder.addTableToFromClause(
-                        rightColumn,
-                        database,
+                StringBuilder joinConditionStringBuilder = new StringBuilder();
+                SqlBuilder.appendCriterion(
+                        join.getJoinCondition(),
                         criteria,
+                        joinConditionStringBuilder,
                         query);
-                queryWhereClause.add(
-                        buildJoinCondition(leftColumn, comparison, rightColumn));
+
+                queryWhereClause.add(joinConditionStringBuilder.toString());
             }
             else
             {
+                Criterion joinCondition = join.getJoinCondition();
+
                 // get the table names
                 // (and the alias names for them if necessary))
-                PreparedStatementPart leftExpression
-                    = SqlBuilder.getExpressionForFromClause(
-                        leftColumn,
-                        database,
-                        criteria);
-
-                PreparedStatementPart rightExpression
-                    = SqlBuilder.getExpressionForFromClause(
-                        rightColumn,
-                        database,
-                        criteria);
+                PreparedStatementPart leftExpression;
+                if (join.getLeftTable() != null)
+                {
+                    leftExpression = join.getLeftTable();
+                }
+                else
+                {
+                    if (joinCondition.isComposite())
+                    {
+                        throw new TorqueException(
+                                "join condition is composite "
+                                + "and there is no leftTable defined "
+                                + "in the join. "
+                                + "Please define a leftTable in the join");
+                    }
+                    Object lValue = joinCondition.getLValue();
+                    leftExpression = SqlBuilder.getExpressionForFromClause(
+                            lValue,
+                            criteria);
+                }
+                PreparedStatementPart rightExpression;
+                if (join.getRightTable() != null)
+                {
+                    rightExpression = join.getRightTable();
+                }
+                else
+                {
+                    if (joinCondition.isComposite())
+                    {
+                        throw new TorqueException(
+                                "join condition is composite "
+                                + "and there is no rightTable defined "
+                                + "in the join. "
+                                + "Please define a rightTable in the join");
+                    }
+                    Object rValue = joinCondition.getRValue();
+                    rightExpression = SqlBuilder.getExpressionForFromClause(
+                            rValue,
+                            criteria);
+
+                }
 
                 // check whether the order of the join must be "reversed"
                 // This if the case if the fromClause already contains
@@ -142,11 +164,7 @@ public final class JoinBuilder
                     FromElement fromElement = new FromElement(
                             rightExpression.getSql().toString(),
                             joinType,
-                            buildJoinCondition(
-                                    leftColumn,
-                                    comparison,
-                                    rightColumn),
-                            rightExpression.getPreparedStatementReplacements());
+                            buildJoinCondition(joinCondition, criteria));
                     queryFromClause.add(fromElement);
                 }
                 else
@@ -156,7 +174,7 @@ public final class JoinBuilder
                                 leftExpression))
                     {
                         // We cannot add an explicit join if both tables
-                        // are alredy present in the from clause
+                        // are already present in the from clause
                         throw new TorqueException(
                                 "Unable to create a" + joinType
                                 + "because both expressions "
@@ -171,9 +189,7 @@ public final class JoinBuilder
                     FromElement fromElement = new FromElement(
                         leftExpression.getSql().toString(),
                         reverseJoinType(joinType),
-                        buildJoinCondition(
-                                leftColumn, comparison, rightColumn),
-                        leftExpression.getPreparedStatementReplacements());
+                        buildJoinCondition(joinCondition, criteria));
                     queryFromClause.add(fromElement);
                 }
             }
@@ -210,21 +226,63 @@ public final class JoinBuilder
     }
 
     /**
-     * Used to specify a join on two columns.
+     * Creates the join condition string for a join.
+     *
+     * @param joinCondition the join condition.
+     * @param criteria the enclosing criteria.
+     *
+     * @return A join expression, e.g. table_a.column_a=table_b.column_b.
      *
-     * @param column A column in one of the tables to be joined.
-     * @param operator the join operator.
-     * @param relatedColumn The column in the other table to be joined.
+     * @throws TorqueException if the join condition cannot be built.
+     */
+    private static PreparedStatementPart buildJoinCondition(
+                Criterion joinCondition,
+                CriteriaInterface<?> criteria)
+            throws TorqueException
+    {
+        PreparedStatementPart joinPart = new PreparedStatementPart();
+        appendJoinCondition(joinCondition, criteria, joinPart);
+        return joinPart;
+    }
 
+    /**
+     * Appends a join condition to a join part.
+     *
+     * @param joinCondition the join condition.
+     * @param criteria the enclosing criteria.
+     * @param joinPart the join part to append to.
+     *
      * @return A join expression, e.g. table_a.column_a=table_b.column_b.
+     *
+     * @throws TorqueException if the join condition cannot be built.
      */
-    private static String buildJoinCondition(
-            Column column,
-            SqlEnum operator,
-            Column relatedColumn)
+    private static void appendJoinCondition(
+                Criterion joinCondition,
+                CriteriaInterface<?> criteria,
+                PreparedStatementPart joinPart)
+            throws TorqueException
     {
-        return column.getSqlExpression()
-            + operator
-            + relatedColumn.getSqlExpression();
+        if (joinCondition.isComposite())
+        {
+            joinPart.getSql().append('(');
+            boolean firstPart = true;
+            for (Criterion part : joinCondition.getParts())
+            {
+                if (!firstPart)
+                {
+                    joinPart.getSql().append(joinCondition.getConjunction());
+                }
+                appendJoinCondition(
+                        part,
+                        criteria,
+                        joinPart);
+                firstPart = false;
+            }
+            joinPart.getSql().append(')');
+            return;
+        }
+        PreparedStatementPart joinConditionStatementPart
+                = SqlBuilder.processCriterion(joinCondition, criteria);
+        joinPart.append(joinConditionStatementPart);
     }
 }

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java Fri Jun  8 04:47:18 2012
@@ -36,6 +36,7 @@ import org.apache.torque.criteria.Criter
 import org.apache.torque.criteria.CriteriaInterface;
 import org.apache.torque.criteria.Criterion;
 import org.apache.torque.criteria.FromElement;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.criteria.SqlEnum;
 import org.apache.torque.map.ColumnMap;
 import org.apache.torque.map.DatabaseMap;
@@ -131,18 +132,14 @@ public final class SqlBuilder
     {
         Query sqlStatement = new Query();
 
-        final String dbName = crit.getDbName();
-        final DB db = Torque.getDB(dbName);
-        final Database database = Torque.getDatabase(dbName);
-
-        JoinBuilder.processJoins(database, crit, sqlStatement);
+        JoinBuilder.processJoins(crit, sqlStatement);
         processModifiers(crit, sqlStatement);
-        processSelectColumns(crit, sqlStatement, database);
-        processAsColumns(crit, sqlStatement, database);
-        processCriterions(db, database, crit, sqlStatement);
-        processGroupBy(crit, database, sqlStatement);
+        processSelectColumns(crit, sqlStatement);
+        processAsColumns(crit, sqlStatement);
+        processCriterions(crit, sqlStatement);
+        processGroupBy(crit, sqlStatement);
         processHaving(crit, sqlStatement);
-        processOrderBy(db, database, crit, sqlStatement);
+        processOrderBy(crit, sqlStatement);
         processLimits(crit, sqlStatement);
 
         return sqlStatement;
@@ -162,18 +159,14 @@ public final class SqlBuilder
     {
         Query sqlStatement = new Query();
 
-        final String dbName = crit.getDbName();
-        final DB db = Torque.getDB(dbName);
-        final Database database = Torque.getDatabase(dbName);
-
-        JoinBuilder.processJoins(database, crit, sqlStatement);
+        JoinBuilder.processJoins(crit, sqlStatement);
         processModifiers(crit, sqlStatement);
-        processSelectColumns(crit, sqlStatement, database);
-        processAsColumns(crit, sqlStatement, database);
-        processCriterions(db, database, crit, sqlStatement);
-        processGroupBy(crit, database, sqlStatement);
+        processSelectColumns(crit, sqlStatement);
+        processAsColumns(crit, sqlStatement);
+        processCriterions(crit, sqlStatement);
+        processGroupBy(crit, sqlStatement);
         processHaving(crit, sqlStatement);
-        processOrderBy(db, database, crit, sqlStatement);
+        processOrderBy(crit, sqlStatement);
         processLimits(crit, sqlStatement);
         processFromElements(crit, sqlStatement);
         sqlStatement.setFetchSize(crit.getFetchSize());
@@ -186,14 +179,12 @@ public final class SqlBuilder
      *
      * @param criteria the criteria from which the select columns are taken.
      * @param query the query to which the select columns should be added.
-     * @param dbName the name of the database to use.
      *
      * @throws TorqueException if the select columns can not be processed.
      */
     private static void processSelectColumns(
                 final CriteriaInterface<?> criteria,
-                final Query query,
-                final Database database)
+                final Query query)
             throws TorqueException
     {
         UniqueList<String> selectClause = query.getSelectClause();
@@ -211,7 +202,6 @@ public final class SqlBuilder
             selectClause.add(sqlExpression);
             addTableToFromClause(
                     column,
-                    database,
                     criteria,
                     query);
         }
@@ -225,14 +215,12 @@ public final class SqlBuilder
      *        not null.
      * @param query the query to which the As-columns should be added,
      *        not null.
-     * @param database the database to use.
      *
      * @throws TorqueException if the as columns can not be processed.
      */
     private static void processAsColumns(
                 final CriteriaInterface<?> criteria,
-                final Query query,
-                final Database database)
+                final Query query)
             throws TorqueException
     {
         UniqueList<String> querySelectClause = query.getSelectClause();
@@ -247,7 +235,6 @@ public final class SqlBuilder
                         + entry.getKey());
             addTableToFromClause(
                     column,
-                    database,
                     criteria,
                     query);
         }
@@ -276,16 +263,12 @@ public final class SqlBuilder
     /**
      * Adds the Criterions from the criteria to the query.
      *
-     * @param db the database for which the query should be created.
-     * @param database the database in which the query should run.
      * @param criteria the criteria from which the Criterion-objects are taken
      * @param query the query to which the Criterion-objects should be added.
      *
      * @throws TorqueException if the Criterion-objects can not be processed
      */
     private static void processCriterions(
-            final DB db,
-            final Database database,
             final Criteria criteria,
             final Query query)
         throws TorqueException
@@ -298,22 +281,21 @@ public final class SqlBuilder
         appendCriterion(
                 criteria.getTopLevelCriterion(),
                 criteria,
-                db,
                 where,
-                database,
                 query);
         query.getWhereClause().add(where.toString());
     }
 
-    private static void appendCriterion(
+    static void appendCriterion(
                 Criterion criterion,
-                Criteria criteria,
-                DB db,
+                CriteriaInterface<?>  criteria,
                 StringBuilder where,
-                Database database,
                 Query query)
             throws TorqueException
     {
+        final String dbName = criteria.getDbName();
+        final Database database = Torque.getDatabase(dbName);
+        final DB db = Torque.getDB(dbName);
         if (criterion.isComposite())
         {
             where.append('(');
@@ -327,9 +309,7 @@ public final class SqlBuilder
                 appendCriterion(
                         part,
                         criteria,
-                        db,
                         where,
-                        database,
                         query);
                 firstPart = false;
             }
@@ -342,15 +322,30 @@ public final class SqlBuilder
         // the joins are processed
         addTableToFromClause(
                 criterion.getLValue(),
-                database,
                 criteria,
                 query);
         addTableToFromClause(
                 criterion.getRValue(),
-                database,
                 criteria,
                 query);
 
+        PreparedStatementPart whereClausePartOutput
+            = processCriterion(criterion, criteria);
+
+        where.append(whereClausePartOutput.getSql());
+        query.getWhereClausePreparedStatementReplacements().addAll(
+                whereClausePartOutput.getPreparedStatementReplacements());
+    }
+
+    static PreparedStatementPart processCriterion(
+                Criterion criterion,
+                CriteriaInterface<?> criteria)
+            throws TorqueException
+    {
+        final String dbName = criteria.getDbName();
+        final Database database = Torque.getDatabase(dbName);
+        final DB db = Torque.getDB(dbName);
+
         boolean ignoreCase
                 = isIgnoreCase(criterion, criteria, database);
 
@@ -379,17 +374,12 @@ public final class SqlBuilder
             throw new RuntimeException("No handler found for whereClausePart "
                     + whereClausePartInput);
         }
-
-        where.append(whereClausePartOutput.getSql());
-        query.getWhereClausePreparedStatementReplacements().addAll(
-                whereClausePartOutput.getPreparedStatementReplacements());
+        return whereClausePartOutput;
     }
 
     /**
      * Adds the Criterions from the criteria to the query.
      *
-     * @param db the database for which the query should be created.
-     * @param database the database in which the query should run.
      * @param criteria the criteria from which the Criterion-objects are taken
      * @param query the query to which the Criterion-objects should be added.
      *
@@ -399,8 +389,6 @@ public final class SqlBuilder
      */
     @Deprecated
     private static void processCriterions(
-            final DB db,
-            final Database database,
             final org.apache.torque.util.Criteria criteria,
             final Query query)
         throws TorqueException
@@ -415,8 +403,6 @@ public final class SqlBuilder
                     criterion,
                     criteria,
                     sb,
-                    db,
-                    database,
                     query);
             whereClause.add(sb.toString());
         }
@@ -431,8 +417,6 @@ public final class SqlBuilder
                 org.apache.torque.util.Criteria.Criterion criterion,
                 org.apache.torque.util.Criteria criteria,
                 StringBuilder sb,
-                DB db,
-                Database database,
                 Query query)
             throws TorqueException
     {
@@ -444,17 +428,18 @@ public final class SqlBuilder
         // the joins are processed
         addTableToFromClause(
             column,
-            database,
             criteria,
             query);
 
         boolean ignoreCase
                 = criteria.isIgnoreCase() || criterion.isIgnoreCase();
+        final String dbName = criteria.getDbName();
+        final DB db = Torque.getDB(dbName);
+        final Database database = Torque.getDatabase(dbName);
         {
             Column databaseColumn = resolveAliasAndAsColumnAndSchema(
                     column,
-                    criteria,
-                    database);
+                    criteria);
             ColumnMap columnMap = null;
             {
                 DatabaseMap databaseMap = database.getDatabaseMap();
@@ -505,8 +490,6 @@ public final class SqlBuilder
                     clause,
                     criteria,
                     sb,
-                    db,
-                    database,
                     query);
             sb.append(')');
         }
@@ -518,8 +501,6 @@ public final class SqlBuilder
      * @throws TorqueException if the OrderBy-Columns can not be processed
      */
     private static void processOrderBy(
-            final DB db,
-            final Database database,
             final CriteriaInterface<?> crit,
             final Query query)
             throws TorqueException
@@ -549,6 +530,7 @@ public final class SqlBuilder
             {
                 if (orderBy.isIgnoreCase() || crit.isIgnoreCase())
                 {
+                    final DB db = Torque.getDB(crit.getDbName());
                     orderByClause.add(
                             db.ignoreCaseInOrderBy(sqlExpression)
                                 + ' ' + orderBy.getOrder());
@@ -574,7 +556,6 @@ public final class SqlBuilder
             }
             addTableToFromClause(
                    column,
-                   database,
                    crit,
                    query);
         }
@@ -584,14 +565,12 @@ public final class SqlBuilder
      * Adds the GroupBy-Columns from the criteria to the query.
      *
      * @param criteria the criteria from which the GroupBy-Columns are taken.
-     * @param database the database.
      * @param query the query to which the GroupBy-Columns should be added.
      *
      * @throws TorqueException if the GroupBy-Columns can not be processed
      */
     private static void processGroupBy(
             final CriteriaInterface<?> criteria,
-            final Database database,
             final Query query)
             throws TorqueException
     {
@@ -611,7 +590,7 @@ public final class SqlBuilder
 
             groupByClause.add(column.getSqlExpression());
             selectClause.add(column.getSqlExpression());
-            addTableToFromClause(column, database, criteria, query);
+            addTableToFromClause(column, criteria, query);
         }
     }
 
@@ -701,22 +680,29 @@ public final class SqlBuilder
      * in the Criteria criteria, getTableNameForFromClause("a", criteria)
      * returns "AUTHOR a".
      *
-     * @param tableName the name of a table
-     *        or the alias for a table
+     * @param toAddToFromClause the column to extract the table name from,
+     *        or a literal object value.
      * @param criteria a criteria object to resolve a possible alias.
      *
-     * @return either the tablename itself if tableOrAliasName is not an alias,
+     * @return A prepared statement part containing either the table name
+     *         itself if tableOrAliasName is not an alias,
      *         or a String of the form "tableName tableOrAliasName"
-     *         if tableOrAliasName is an alias for a table name
+     *         if tableOrAliasName is an alias for a table name,
+     *         or a ? with the replacement if toAddToFromClause is not a Column.
      */
     static PreparedStatementPart getExpressionForFromClause(
-            final Column column,
-            final Database database,
+            final Object toAddToFromClause,
             final CriteriaInterface<?> criteria)
             throws TorqueException
     {
+        if (!(toAddToFromClause instanceof Column))
+        {
+            // toAddToFromClause is a literal Value
+            return new PreparedStatementPart("?", toAddToFromClause);
+        }
+        Column column = (Column) toAddToFromClause;
         Column resolvedColumn
-                = resolveAliasAndAsColumnAndSchema(column, criteria, database);
+                = resolveAliasAndAsColumnAndSchema(column, criteria);
         String fullTableName
                 = resolvedColumn.getFullTableName();
 
@@ -913,17 +899,18 @@ public final class SqlBuilder
     }
 
     /**
-     * Returns the database name of a column
+     * Returns the database name of a column.
+     *
      * @param tableName the name of a table or the alias for a table.
-     * @param criteria a criteria object to resolve a possible alias,
+     * @param criteria a criteria object to resolve a possible alias.
+     *
      * @return either the tablename itself if tableOrAliasName is not an alias,
      *         or a String of the form "tableName tableOrAliasName"
      *         if tableOrAliasName is an alias for a table name
      */
     static Column resolveAliasAndAsColumnAndSchema(
             final Column columnToResolve,
-            final CriteriaInterface<?> criteria,
-            Database database)
+            final CriteriaInterface<?> criteria)
             throws TorqueException
     {
         String columnNameToResolve = columnToResolve.getColumnName();
@@ -952,6 +939,8 @@ public final class SqlBuilder
         String resolvedSchemaName = resolvedColumn.getSchemaName();
         if (resolvedSchemaName == null)
         {
+            final String dbName = criteria.getDbName();
+            final Database database = Torque.getDatabase(dbName);
             resolvedSchemaName = database.getSchema();
         }
         if (sqlExpressionModified)
@@ -1018,7 +1007,6 @@ public final class SqlBuilder
      */
     static void addTableToFromClause(
                 final Object possibleColumn,
-                final Database database,
                 final CriteriaInterface<?> criteria,
                 Query query)
             throws TorqueException
@@ -1038,7 +1026,6 @@ public final class SqlBuilder
         }
         PreparedStatementPart fromClauseExpression = getExpressionForFromClause(
                 column,
-                database,
                 criteria);
 
         UniqueList<FromElement> queryFromClause = query.getFromClause();
@@ -1128,8 +1115,7 @@ public final class SqlBuilder
         Column column = (Column) value;
         Column databaseColumn = resolveAliasAndAsColumnAndSchema(
                 column,
-                criteria,
-                database);
+                criteria);
         ColumnMap columnMap = null;
         {
             DatabaseMap databaseMap = database.getDatabaseMap();

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/WhereClauseExpression.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/WhereClauseExpression.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/WhereClauseExpression.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/WhereClauseExpression.java Fri Jun  8 04:47:18 2012
@@ -87,7 +87,7 @@ public class WhereClauseExpression
         if ((lValue == null || operator == null)
                 && (sql == null))
         {
-            throw new IllegalArgumentException("Eitherthe values"
+            throw new IllegalArgumentException("Either the values"
                     + "(lValue, comparison) or "
                     + "sql must be not null");
         }

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectOrColumnPsPartBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectOrColumnPsPartBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectOrColumnPsPartBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectOrColumnPsPartBuilder.java Fri Jun  8 04:47:18 2012
@@ -23,9 +23,9 @@ import org.apache.torque.Column;
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
 import org.apache.torque.criteria.Criteria;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.criteria.SqlEnum;
 import org.apache.torque.om.ObjectKey;
-import org.apache.torque.sql.PreparedStatementPart;
 import org.apache.torque.sql.Query;
 import org.apache.torque.sql.SqlBuilder;
 

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectPsPartBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectPsPartBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectPsPartBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/objectbuilder/ObjectPsPartBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,7 +21,7 @@ package org.apache.torque.sql.objectbuil
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
-import org.apache.torque.sql.PreparedStatementPart;
+import org.apache.torque.criteria.PreparedStatementPart;
 
 /**
  * Builds a PreparedStatementPart from a single object

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CurrentDateTimePsPartBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CurrentDateTimePsPartBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CurrentDateTimePsPartBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CurrentDateTimePsPartBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,8 +21,8 @@ package org.apache.torque.sql.whereclaus
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.criteria.SqlEnum;
-import org.apache.torque.sql.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CustomBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CustomBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CustomBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/CustomBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,8 +21,8 @@ package org.apache.torque.sql.whereclaus
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.criteria.SqlEnum;
-import org.apache.torque.sql.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/InBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/InBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/InBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/InBuilder.java Fri Jun  8 04:47:18 2012
@@ -27,8 +27,8 @@ import org.apache.torque.TorqueException
 import org.apache.torque.adapter.DB;
 import org.apache.torque.criteria.Criteria;
 import org.apache.torque.criteria.Criterion;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.criteria.SqlEnum;
-import org.apache.torque.sql.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/LikeBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/LikeBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/LikeBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/LikeBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,8 +21,8 @@ package org.apache.torque.sql.whereclaus
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.criteria.SqlEnum;
-import org.apache.torque.sql.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/NullValueBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/NullValueBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/NullValueBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/NullValueBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,8 +21,8 @@ package org.apache.torque.sql.whereclaus
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.criteria.SqlEnum;
-import org.apache.torque.sql.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/StandardBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/StandardBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/StandardBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/StandardBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,7 +21,7 @@ package org.apache.torque.sql.whereclaus
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
-import org.apache.torque.sql.PreparedStatementPart;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/VerbatimSqlConditionBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/VerbatimSqlConditionBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/VerbatimSqlConditionBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/VerbatimSqlConditionBuilder.java Fri Jun  8 04:47:18 2012
@@ -23,7 +23,7 @@ import java.util.Arrays;
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
-import org.apache.torque.sql.PreparedStatementPart;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/WhereClausePsPartBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/WhereClausePsPartBuilder.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/WhereClausePsPartBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/whereclausebuilder/WhereClausePsPartBuilder.java Fri Jun  8 04:47:18 2012
@@ -21,7 +21,7 @@ package org.apache.torque.sql.whereclaus
 
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DB;
-import org.apache.torque.sql.PreparedStatementPart;
+import org.apache.torque.criteria.PreparedStatementPart;
 import org.apache.torque.sql.WhereClauseExpression;
 
 /**

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java Fri Jun  8 04:47:18 2012
@@ -468,8 +468,7 @@ public class BasePeerImpl implements Ser
         }
         if (!ownTableAdded)
         {
-            query.getFromClause().add(
-                    new FromElement(fullTableName, null, null));
+            query.getFromClause().add(new FromElement(fullTableName));
         }
         String sql = query.toString();
 
@@ -564,8 +563,7 @@ public class BasePeerImpl implements Ser
         }
         if (!ownTableAdded)
         {
-            query.getFromClause().add(
-                    new FromElement(fullTableName, null, null));
+            query.getFromClause().add(new FromElement(fullTableName));
         }
         String sql = query.toString();
 
@@ -1161,8 +1159,7 @@ public class BasePeerImpl implements Ser
             String tableName = SqlBuilder.getFullTableName(
                     defaultTableMap.getName(),
                     criteria.getDbName());
-            query.getFromClause().add(
-                    new FromElement(tableName, null, null));
+            query.getFromClause().add(new FromElement(tableName));
         }
 
         PreparedStatement statement = null;
@@ -1313,8 +1310,7 @@ public class BasePeerImpl implements Ser
             String tableName = SqlBuilder.getFullTableName(
                     defaultTableMap.getName(),
                     criteria.getDbName());
-            query.getFromClause().add(
-                    new FromElement(tableName, null, null));
+            query.getFromClause().add(new FromElement(tableName));
         }
 
         PreparedStatement statement = null;
@@ -1730,8 +1726,7 @@ public class BasePeerImpl implements Ser
         String fullTableName = SqlBuilder.getFullTableName(
                 updateValues.getTable().getName(),
                 criteria.getDbName());
-        query.getFromClause().add(
-                new FromElement(fullTableName, null, null));
+        query.getFromClause().add(new FromElement(fullTableName));
 
         List<JdbcTypedValue> replacementObjects
                 = new ArrayList<JdbcTypedValue>();
@@ -1828,8 +1823,7 @@ public class BasePeerImpl implements Ser
         String fullTableName = SqlBuilder.getFullTableName(
                 updateValues.getTable().getName(),
                 criteria.getDbName());
-        query.getFromClause().add(
-                new FromElement(fullTableName, null, null));
+        query.getFromClause().add(new FromElement(fullTableName));
 
         List<JdbcTypedValue> replacementObjects
                 = new ArrayList<JdbcTypedValue>();

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java Fri Jun  8 04:47:18 2012
@@ -1283,7 +1283,7 @@ public class Criteria implements Seriali
      */
     public Criteria addJoin(Column left, Column right, JoinType operator)
     {
-        joins.add(new Join(left, right, operator));
+        joins.add(new Join(left, right, Criteria.EQUAL, operator));
 
         return this;
     }
@@ -1331,6 +1331,7 @@ public class Criteria implements Seriali
         joins.add(new Join(
                 new ColumnImpl(left),
                 new ColumnImpl(right),
+                Criteria.EQUAL,
                 operator));
 
         return this;

Modified: db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/CriteriaTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/CriteriaTest.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/CriteriaTest.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/CriteriaTest.java Fri Jun  8 04:47:18 2012
@@ -675,9 +675,9 @@ public class CriteriaTest extends BaseTe
         List<Join> joinsClone = cClone.getJoins();
         Join joinClone = joinsClone.get(0);
         assertEquals(new ColumnImpl("Author", "AUTHOR_ID"),
-                joinClone.getLeftColumn());
+                joinClone.getJoinCondition().getLValue());
         assertEquals(new ColumnImpl("Book", "AUTHOR_ID"),
-                joinClone.getRightColumn());
+                joinClone.getJoinCondition().getRValue());
         assertEquals(Criteria.INNER_JOIN, joinClone.getJoinType());
         assertEquals(c.getJoins(), cClone.getJoins());
 
@@ -768,9 +768,9 @@ public class CriteriaTest extends BaseTe
         List<Join> joinsClone = cClone.getJoins();
         Join joinClone = joinsClone.get(0);
         assertEquals(new ColumnImpl("Author", "AUTHOR_ID"),
-                joinClone.getLeftColumn());
+                joinClone.getJoinCondition().getLValue());
         assertEquals(new ColumnImpl("Book", "AUTHOR_ID"),
-                joinClone.getRightColumn());
+                joinClone.getJoinCondition().getRValue());
         assertEquals(Criteria.INNER_JOIN, joinClone.getJoinType());
         assertEquals(c.getJoins(), cClone.getJoins());
 

Modified: db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/JoinTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/JoinTest.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/JoinTest.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/criteria/JoinTest.java Fri Jun  8 04:47:18 2012
@@ -34,10 +34,12 @@ public class JoinTest extends BaseTestCa
         Join join = new Join(
                 new ColumnImpl("myTable1", "myColumn1"),
                 new ColumnImpl("myTable2", "myColumn2"),
+                Criteria.EQUAL,
                 Criteria.LEFT_JOIN);
         Join compareToJoin = new Join(
                 new ColumnImpl("myTable1", "myColumn1"),
                 new ColumnImpl("myTable2", "myColumn2"),
+                Criteria.EQUAL,
                 Criteria.LEFT_JOIN);
         assertEquals(join.hashCode(), compareToJoin.hashCode());
         assertEquals(join, compareToJoin);
@@ -49,9 +51,10 @@ public class JoinTest extends BaseTestCa
         Join join = new Join(
                 new ColumnImpl("myTable1", "myColumn1"),
                 new ColumnImpl("myTable2", "myColumn2"),
+                Criteria.NOT_EQUAL,
                 Criteria.LEFT_JOIN);
-        assertEquals(" LEFT JOIN  : myTable1.myColumn1=myTable2.myColumn2 "
-                + "(ignoreCase not considered)",
+        assertEquals(" LEFT JOIN (null, null): "
+                    + "myTable1.myColumn1<>myTable2.myColumn2",
                 join.toString());
     }
 }

Modified: db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/QueryTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/QueryTest.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/QueryTest.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/QueryTest.java Fri Jun  8 04:47:18 2012
@@ -66,8 +66,8 @@ public class QueryTest extends BaseTestC
 
         UniqueList<FromElement> tables = query.getFromClause();
         tables.clear();
-        tables.add(new FromElement("tableA", null, null));
-        tables.add(new FromElement("tableB", null, null));
+        tables.add(new FromElement("tableA"));
+        tables.add(new FromElement("tableB"));
 
         UniqueList<String> where = query.getWhereClause();
         where.clear();

Modified: db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java Fri Jun  8 04:47:18 2012
@@ -32,6 +32,7 @@ import org.apache.torque.TorqueException
 import org.apache.torque.criteria.Criteria;
 import org.apache.torque.criteria.Criterion;
 import org.apache.torque.criteria.FromElement;
+import org.apache.torque.criteria.SqlEnum;
 import org.apache.torque.om.NumberKey;
 
 /**
@@ -45,7 +46,7 @@ public class SqlBuilderTest extends Base
 {
 	/** Time limit in ms of builing a query from a large array. */
 	private static final long LARGE_ARRAY_TIME_LIMIT = 100L;
-	
+
     /**
      * Test where condition with several ANDs compairing against Strings.
      */
@@ -926,9 +927,12 @@ public class SqlBuilderTest extends Base
         Criteria criteria = new Criteria();
         criteria.addSelectColumn(new ColumnImpl("table1.column"));
         criteria.addJoin(
-                new ColumnImpl("table1.column1"),
-                Criteria.NOT_EQUAL,
-                new ColumnImpl("table2.column2"),
+                "table1",
+                "table2",
+                new Criterion(
+                    new ColumnImpl("table1.column1"),
+                    new ColumnImpl("table2.column2"),
+                    SqlEnum.NOT_EQUAL),
                 null);
         Query query = SqlBuilder.buildQuery(criteria);
         assertEquals(
@@ -984,14 +988,20 @@ public class SqlBuilderTest extends Base
         Criteria criteria = new Criteria();
         criteria.addSelectColumn(new ColumnImpl("table1.column1"));
         criteria.addJoin(
-                new ColumnImpl("table2.column2"),
-                Criteria.LESS_THAN,
-                new ColumnImpl("table3.column3"),
+                "table2",
+                "table3",
+                new Criterion(
+                    new ColumnImpl("table2.column2"),
+                    new ColumnImpl("table3.column3"),
+                    Criteria.LESS_THAN),
                 Criteria.INNER_JOIN);
         criteria.addJoin(
-                new ColumnImpl("table1.column1"),
-                Criteria.GREATER_THAN,
-                new ColumnImpl("table2.column2"),
+                "table1",
+                "table2",
+                new Criterion(
+                    new ColumnImpl("table1.column1"),
+                    new ColumnImpl("table2.column2"),
+                    Criteria.GREATER_THAN),
                 Criteria.INNER_JOIN);
         Query query = SqlBuilder.buildQuery(criteria);
         // second join condition must be changed in order to satisfy
@@ -1036,6 +1046,38 @@ public class SqlBuilderTest extends Base
         }
     }
 
+    public void testInnerJoinExplicitWithComplicatedCondition()
+            throws Exception
+    {
+        Criterion join1 = new Criterion(new ColumnImpl("table1.column2"), "x");
+        Criterion join2 = new Criterion(
+                "y",
+                new ColumnImpl("table2.column2"),
+                SqlEnum.NOT_EQUAL);
+        join2.setIgnoreCase(true);
+        Criterion join3 = new Criterion(
+                new ColumnImpl("table1.column2"),
+                new ColumnImpl("table2.column2"));
+        Criterion join = new Criterion(join1).and(join2).and(join3);
+
+        Criteria criteria = new Criteria();
+        criteria.setDbName(databasePostgresql.getName());
+        criteria.addSelectColumn(new ColumnImpl("table1.column1"));
+        criteria.addJoin("table1", "table2", join, Criteria.INNER_JOIN);
+
+        Query query = SqlBuilder.buildQuery(criteria);
+
+        assertEquals(
+                "SELECT table1.column1 FROM table1 INNER JOIN table2 "
+                   + "ON (table1.column2=? "
+                   + "AND UPPER(?)<>UPPER(table2.column2) "
+                   + "AND table1.column2=table2.column2)",
+                query.toString());
+        assertEquals(2, query.getPreparedStatementReplacements().size());
+        assertEquals("x", query.getPreparedStatementReplacements().get(0));
+        assertEquals("y", query.getPreparedStatementReplacements().get(1));
+    }
+
     public void testLeftJoin()
             throws Exception
     {
@@ -1235,6 +1277,40 @@ public class SqlBuilderTest extends Base
         assertEquals("x", query.getPreparedStatementReplacements().get(0));
     }
 
+    public void testInnerJoinImplicitWithComplicatedCondition()
+            throws Exception
+    {
+        Criterion join1 = new Criterion(new ColumnImpl("table1.column2"), "x");
+        Criterion join2 = new Criterion(
+                "y",
+                new ColumnImpl("table2.column2"),
+                SqlEnum.NOT_EQUAL);
+        join2.setIgnoreCase(true);
+        Criterion join3 = new Criterion(
+                new ColumnImpl("table1.column2"),
+                new ColumnImpl("table2.column2"));
+        Criterion join = new Criterion(join1).and(join2).and(join3);
+
+        Criteria criteria = new Criteria();
+        criteria.setDbName(databasePostgresql.getName());
+        criteria.addSelectColumn(new ColumnImpl("table1.column1"));
+        criteria.addJoin("table1", "table2", join, null);
+        criteria.where(new ColumnImpl("table1.column3"), null, Criteria.ISNULL);
+
+        Query query = SqlBuilder.buildQuery(criteria);
+
+        assertEquals(
+                "SELECT table1.column1 FROM table1, table2 "
+                   + "WHERE (table1.column2=? "
+                   + "AND UPPER(?)<>UPPER(table2.column2) "
+                   + "AND table1.column2=table2.column2) "
+                   + "AND table1.column3 IS NULL",
+                query.toString());
+        assertEquals(2, query.getPreparedStatementReplacements().size());
+        assertEquals("x", query.getPreparedStatementReplacements().get(0));
+        assertEquals("y", query.getPreparedStatementReplacements().get(1));
+    }
+
     public void testDistinct()
             throws Exception
     {
@@ -1947,7 +2023,7 @@ public class SqlBuilderTest extends Base
         List<Object> replacements = query.getPreparedStatementReplacements();
         assertEquals(size, replacements.size());
         // time limit 50 ms
-        assertTrue("Exceeded time limit of " + LARGE_ARRAY_TIME_LIMIT 
+        assertTrue("Exceeded time limit of " + LARGE_ARRAY_TIME_LIMIT
         		  + " ms. Execution time was " + (end - start) + " ms",
         		end - start < LARGE_ARRAY_TIME_LIMIT);
     }

Modified: db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/CriteriaTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/CriteriaTest.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/CriteriaTest.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/CriteriaTest.java Fri Jun  8 04:47:18 2012
@@ -585,8 +585,11 @@ public class CriteriaTest extends BaseTe
         // Check Joins
         List joinsClone = cClone.getJoins();
         Join joinClone = (Join) joinsClone.get(0);
-        assertEquals(new ColumnImpl("Author", "AUTHOR_ID"), joinClone.getLeftColumn());
-        assertEquals(new ColumnImpl("Book", "AUTHOR_ID"), joinClone.getRightColumn());
+        assertEquals(
+                new ColumnImpl("Author", "AUTHOR_ID"),
+                joinClone.getJoinCondition().getLValue());
+        assertEquals(new ColumnImpl("Book", "AUTHOR_ID"),
+                joinClone.getJoinCondition().getRValue());
         assertEquals(Criteria.INNER_JOIN, joinClone.getJoinType());
         assertEquals(c.getJoins(), cClone.getJoins());
 

Modified: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/JoinTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/JoinTest.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/JoinTest.java (original)
+++ db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/JoinTest.java Fri Jun  8 04:47:18 2012
@@ -10,6 +10,7 @@ import org.apache.torque.Torque;
 import org.apache.torque.TorqueException;
 import org.apache.torque.adapter.DBHsqldb;
 import org.apache.torque.criteria.Criteria;
+import org.apache.torque.criteria.Criterion;
 import org.apache.torque.test.A;
 import org.apache.torque.test.APeer;
 import org.apache.torque.test.Author;
@@ -163,9 +164,12 @@ public class JoinTest extends BaseDataba
         insertTestData();
         Criteria criteria = new Criteria();
         criteria.addJoin(
-                BookPeer.AUTHOR_ID,
-                Criteria.NOT_EQUAL,
-                AuthorPeer.AUTHOR_ID,
+                BookPeer.TABLE_NAME,
+                AuthorPeer.TABLE_NAME,
+                    new Criterion(
+                    BookPeer.AUTHOR_ID,
+                    AuthorPeer.AUTHOR_ID,
+                    Criteria.NOT_EQUAL),
                 null);
 
         List<Author> authorList = AuthorPeer.doSelect(criteria);
@@ -259,7 +263,7 @@ public class JoinTest extends BaseDataba
     }
 
     /**
-     * Test an implicit inner join with a subselect
+     * Test an implicit inner join with a subselect.
      * Reversed means that torque needs to change a right join to a left
      * join and change tables to create a valid sql statement.
      *
@@ -300,6 +304,71 @@ public class JoinTest extends BaseDataba
         assertEquals("Author with one book", authorList.get(0).getName());
     }
 
+    /**
+     * Test an implicit inner join where the join condition consists of two
+     * conditions joined with AND.
+     *
+     * @throws Exception if the test fails.
+     */
+    public void testImplicitInnerJoinTwoConditions() throws Exception
+    {
+        cleanBookstore();
+        insertTestData();
+        Criteria criteria = new Criteria();
+        Criterion joinCondition = new Criterion(AuthorPeer.AUTHOR_ID,
+                BookPeer.AUTHOR_ID);
+        joinCondition.and(new Criterion(BookPeer.TITLE, "Book 1"));
+        criteria.addJoin(
+                AuthorPeer.TABLE_NAME,
+                BookPeer.TABLE_NAME,
+                joinCondition,
+                null);
+
+        List<Author> authorList = AuthorPeer.doSelect(criteria);
+
+        // Here we get 1 authors:
+        // the author with one book,
+        if (authorList.size() != 1)
+        {
+            fail("author join book : "
+                     + "incorrect numbers of authors found : "
+                     + authorList.size()
+                     + ", should be 1");
+        }
+    }
+
+    /**
+     * Test an implicit inner join where the join condition consists of two
+     * conditions joined with AND.
+     *
+     * @throws Exception if the test fails.
+     */
+    public void testExplicitInnerJoinTwoConditions() throws Exception
+    {
+        cleanBookstore();
+        insertTestData();
+        Criteria criteria = new Criteria();
+        Criterion joinCondition = new Criterion(AuthorPeer.AUTHOR_ID,
+                BookPeer.AUTHOR_ID);
+        joinCondition.and(new Criterion(BookPeer.TITLE, "Book 1"));
+        criteria.addJoin(
+                AuthorPeer.TABLE_NAME,
+                BookPeer.TABLE_NAME,
+                joinCondition,
+                Criteria.INNER_JOIN);
+
+        List<Author> authorList = AuthorPeer.doSelect(criteria);
+
+        // Here we get 1 authors:
+        // the author with one book,
+        if (authorList.size() != 1)
+        {
+            fail("author join book : "
+                     + "incorrect numbers of authors found : "
+                     + authorList.size()
+                     + ", should be 1");
+        }
+    }
 
     /**
      * Test joins using the XPeer.DoSelectJoinYYY methods

Modified: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/oid/IDBrokerTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/oid/IDBrokerTest.java?rev=1347879&r1=1347878&r2=1347879&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/oid/IDBrokerTest.java (original)
+++ db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/oid/IDBrokerTest.java Fri Jun  8 04:47:18 2012
@@ -78,7 +78,7 @@ public class IDBrokerTest extends BaseDa
     }
 
     /**
-     * Tests that the quanitity value is initially set to 10.
+     * Tests that the quantity value is initially set to 10.
      *
      * @throws Exception if the test fails
      */



---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org