You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by br...@apache.org on 2003/01/19 12:50:58 UTC

cvs commit: jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer StatementManager.java

brj         2003/01/19 03:50:58

  Modified:    src/java/org/apache/ojb/broker/accesslayer/sql
                        SqlQueryStatement.java SqlDeleteByQuery.java
               src/java/org/apache/ojb/broker/accesslayer
                        StatementManager.java
  Log:
  enhancements for extent aware path expressions
  
  Revision  Changes    Path
  1.19      +270 -135  jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlQueryStatement.java
  
  Index: SqlQueryStatement.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlQueryStatement.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- SqlQueryStatement.java	5 Jan 2003 09:25:33 -0000	1.18
  +++ SqlQueryStatement.java	19 Jan 2003 11:50:57 -0000	1.19
  @@ -54,36 +54,25 @@
    * <http://www.apache.org/>.
    */
   
  +import java.util.ArrayList;
  +import java.util.Collection;
  +import java.util.Enumeration;
  +import java.util.HashMap;
  +import java.util.Iterator;
  +import java.util.List;
  +
   import org.apache.ojb.broker.accesslayer.JoinSyntaxTypes;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.CollectionDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  -import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
   import org.apache.ojb.broker.metadata.FieldHelper;
  +import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
   import org.apache.ojb.broker.platforms.Platform;
  -import org.apache.ojb.broker.query.BetweenCriteria;
  -import org.apache.ojb.broker.query.ColumnCriteria;
  -import org.apache.ojb.broker.query.Criteria;
  -import org.apache.ojb.broker.query.ExistsCriteria;
  -import org.apache.ojb.broker.query.FieldCriteria;
  -import org.apache.ojb.broker.query.InCriteria;
  -import org.apache.ojb.broker.query.MtoNQuery;
  -import org.apache.ojb.broker.query.NullCriteria;
  -import org.apache.ojb.broker.query.Query;
  -import org.apache.ojb.broker.query.QueryByCriteria;
  -import org.apache.ojb.broker.query.SelectionCriteria;
  -import org.apache.ojb.broker.query.SqlCriteria;
  +import org.apache.ojb.broker.query.*;
   import org.apache.ojb.broker.util.SqlHelper;
  +import org.apache.ojb.broker.util.SqlHelper.PathInfo;
   import org.apache.ojb.broker.util.logging.Logger;
   
  -import java.util.ArrayList;
  -import java.util.Collection;
  -import java.util.Enumeration;
  -import java.util.HashMap;
  -import java.util.HashSet;
  -import java.util.Iterator;
  -import java.util.List;
  -
   /**
    * Model a Statement based on Query.
    *
  @@ -135,71 +124,118 @@
       }
   
       /**
  -     * Answer the appropriate ColumnName <br>
  -     * if a FIELDDESCRIPTOR is found for the Criteria the colName is taken from
  -     * there otherwise its taken from Criteria. <br>
  -     * field names in functions (ie: sum(name) ) are tried to resolve
  -     * ie: name from FIELDDESCRIPTOR , UPPER(name_test) from Criteria<br>
  +     * Return the TableAlias and the PathInfo for an Attribute name<br>
  +     * field names in functions (ie: sum(name) ) are tried to resolve ie: name
  +     * from FIELDDESCRIPTOR , UPPER(name_test) from Criteria<br> 
        * also resolve pathExpression adress.city or owner.konti.saldo
  +     * @param attr
  +     * @param useOuterJoins
  +     * @return ColumnInfo
  +     */
  +    protected AttributeInfo getAttributeInfo(String attr, boolean useOuterJoins)
  +    {
  +        AttributeInfo result = new AttributeInfo();
  +        TableAlias alias = getRoot();
  +        SqlHelper.PathInfo pathInfo = SqlHelper.splitPath(attr);
  +        String colName = pathInfo.column;
  +        int sp;
  +
  +        sp = colName.lastIndexOf(".");    
  +        if (sp >= 0)
  +        {
  +            String pathName = colName.substring(0, sp);
  +            String fieldName = colName.substring(sp + 1);;
  +
  +            alias = getTableAlias(pathName, useOuterJoins);
  +            if (alias != null)
  +            {
  +                // correct column name to match the alias
  +                // productGroup.groupName -> groupName
  +                pathInfo.column = fieldName;
  +            }
  +        }
  +        
  +        result.tableAlias = alias;
  +        result.pathInfo = pathInfo;
  +        return result;
  +    }
  +    
  +    /**
  +     * Add the Column to the StringBuffer <br>
  +     * if a FieldDescriptor is found for the Criteria the colName is taken from
  +     * there otherwise its taken from Criteria. <br>
  +     * @param alias
  +     * @param pathInfo
  +     * @param buf
  +     */
  +	protected void appendColName(TableAlias alias, PathInfo pathInfo, StringBuffer buf)
  +	{
  +		FieldDescriptor fld = getField(alias, pathInfo);
  +		String functionName = pathInfo.function;
  +		String colName = pathInfo.column;
  +
  +        
  +        if (functionName != null) // rebuild function contains (
  +        {
  +            buf.append(functionName);
  +        }
  +
  +        if (fld != null)
  +        {
  +            buf.append(alias.alias);
  +            buf.append(".");
  +            buf.append(fld.getColumnName());
  +        }
  +        else
  +        {
  +            buf.append(colName);
  +        }
  +
  +        if (functionName != null) // rebuild function
  +        {
  +            buf.append(")");
  +        }
  +    }
  +
  +    /**
  +     * Get the FieldDescriptor for the PathInfo
  +     * @param alias
  +     * @param pathInfo
  +     * @return FieldDescriptor
        */
  -	protected void appendColName(String attr, boolean useOuterJoins, StringBuffer buf)
  +	protected FieldDescriptor getField(TableAlias alias, PathInfo pathInfo)
   	{
   		FieldDescriptor fld = null;
  -		SqlHelper.PathInfo pi = SqlHelper.splitPath(attr);
  -		String functionName = pi.function;
  -		String colName = pi.column;
  -		int sp;
  -		TableAlias alias = null;
  +		String colName = pathInfo.column;
   
  -		sp = colName.lastIndexOf(".");
  -		if (sp == -1)
  +		if (alias != null)
   		{
  -			fld = getRoot().cld.getFieldDescriptorByName(colName);
  +			fld = alias.cld.getFieldDescriptorByName(colName);
   			if (fld == null)
   			{
  -				/**
  -				 * MBAIRD
  -				 * possible we've referred to an object not by key, ie is_undefined(obj) instead of
  -				 * is_undefined(obj.pkField)
  -				 * I don't know how to join on multiple FK fields, so check the first one.
  -				 */
  -				ObjectReferenceDescriptor ord = getRoot().cld.getObjectReferenceDescriptorByName(colName);
  +				ObjectReferenceDescriptor ord = alias.cld.getObjectReferenceDescriptorByName(colName);
   				if (ord != null)
   				{
  -					FieldDescriptor[] fk = ord.getForeignKeyFieldDescriptors(getRoot().cld);
  -					if (fk.length > 0)
  +					if (alias == getRoot())
   					{
  -						fld = fk[0];
  +						// no path expression
  +						FieldDescriptor[] fk = ord.getForeignKeyFieldDescriptors(alias.cld);
  +						if (fk.length > 0)
  +						{
  +							fld = fk[0];
  +						}
   					}
  -				}
  -			}
  -			alias = getRoot();
  -		}
  -		else
  -		{
  -			String fieldName = colName.substring(sp + 1);
  -			String pathName = colName.substring(0, sp);
  -			alias = getTableAlias(pathName, useOuterJoins);
  -			if (alias != null)
  -			{
  -				fld = alias.cld.getFieldDescriptorByName(fieldName);
  -				if (fld == null)
  -				{
  -					/**
  -					 * MBAIRD
  -					 * potentially people are referring to objects, not to the object's primary key, and then we need to take the
  -					 * primary key attribute of the referenced object to help them out.
  -					 */
  -					ObjectReferenceDescriptor ord = alias.cld.getObjectReferenceDescriptorByName(fieldName);
  -					if (ord != null)
  +					else
   					{
  +						// attribute with path expression
  +						/**
  +						 * MBAIRD
  +						 * potentially people are referring to objects, not to the object's primary key, and then we need to take the
  +						 * primary key attribute of the referenced object to help them out.
  +						 */
   						ClassDescriptor cld = alias.cld.getRepository().getDescriptorFor(ord.getItemClass());
   						if (cld != null)
   						{
  -							/**
  -							 * MBAIRD
  -							 * just take the first one as no way to specify two values for primary key?
  -							 */
   							fld = alias.cld.getFieldDescriptorByName(cld.getPkFields()[0].getPersistentField().getName());
   						}
   					}
  @@ -207,27 +243,24 @@
   			}
   		}
   
  -		if (functionName != null) // rebuild function
  -		{
  -			buf.append(functionName);
  -		}
  -
  -		if (fld != null)
  -		{
  -			buf.append(alias.alias);
  -			buf.append(".");
  -			buf.append(fld.getColumnName());
  -		}
  -		else
  -		{
  -			buf.append(colName);
  -		}
  -
  -		if (functionName != null) // rebuild function
  -		{
  -			buf.append(")");
  -		}
  +		return fld;
   	}
  +    
  +    /**
  +     * Answer the appropriate ColumnName <br>
  +     * if a FIELDDESCRIPTOR is found for the Criteria the colName is taken from
  +     * there otherwise its taken from Criteria. <br>
  +     * field names in functions (ie: sum(name) ) are tried to resolve
  +     * ie: name from FIELDDESCRIPTOR , UPPER(name_test) from Criteria<br>
  +     * also resolve pathExpression adress.city or owner.konti.saldo
  +     */
  +    protected void appendColName(String attr, boolean useOuterJoins, StringBuffer buf)
  +    {
  +        AttributeInfo attrInfo = getAttributeInfo(attr, useOuterJoins);
  +        TableAlias alias = attrInfo.tableAlias;
  +            
  +        appendColName(alias, attrInfo.pathInfo, buf);
  +    }
   
       /**
        * appends a WHERE-clause to the Statement
  @@ -340,11 +373,14 @@
       /**
        * Answer the SQL-Clause for a BetweenCriteria
        *
  +     * @param alias
  +     * @param pathInfo
        * @param c BetweenCriteria
  +     * @param buf
        */
  -    private void appendSQLClause(BetweenCriteria c, StringBuffer buf)
  +    private void appendBetweenCriteria(TableAlias alias, PathInfo pathInfo, BetweenCriteria c, StringBuffer buf)
       {
  -        appendColName(c.getAttribute(), false, buf);
  +        appendColName(alias, pathInfo, buf);
           buf.append(c.getClause());
           appendParameter(c.getValue(), buf);
           buf.append("AND");
  @@ -353,21 +389,24 @@
   
       /**
        * Answer the SQL-Clause for a ColumnCriteria
  -     *
  +     * 
  +     * @param alias
  +     * @param pathInfo
        * @param c ColumnCriteria
  +     * @param buf
        */
  -    private void appendSQLClause(ColumnCriteria c, StringBuffer buf)
  +    private void appendColumnCriteria(TableAlias alias, PathInfo pathInfo, ColumnCriteria c, StringBuffer buf)
       {
  -        appendColName(c.getAttribute(), false, buf);
  +        appendColName(alias, pathInfo, buf);
           buf.append(c.getClause());
  -        appendColName((String) c.getValue(), false, buf);
  +        buf.append(c.getValue());
       }
   
       /**
        * Answer the SQL-Clause for an ExistsCriteria
        * @param c ExistsCriteria
        */
  -    private void appendSQLClause(ExistsCriteria c, StringBuffer buf)
  +    private void appendExistsCriteria(ExistsCriteria c, StringBuffer buf)
       {
           Query subQuery = (Query) c.getValue();
   
  @@ -378,11 +417,14 @@
       /**
        * Answer the SQL-Clause for a FieldCriteria
        *
  -     * @param c FieldCriteria
  +     * @param alias
  +     * @param pathInfo
  +     * @param c ColumnCriteria
  +     * @param buf
        */
  -    private void appendSQLClause(FieldCriteria c, StringBuffer buf)
  +    private void appendFieldCriteria(TableAlias alias, PathInfo pathInfo,FieldCriteria c, StringBuffer buf)
       {
  -        appendColName(c.getAttribute(), false, buf);
  +        appendColName(alias, pathInfo, buf);
           buf.append(c.getClause());
           appendColName((String) c.getValue(), false, buf);
       }
  @@ -390,11 +432,14 @@
       /**
        * Answer the SQL-Clause for an InCriteria
        *
  -     * @param c SelectionCriteria
  +     * @param alias
  +     * @param pathInfo
  +     * @param c InCriteria
  +     * @param buf
        */
  -    private void appendSQLClause(InCriteria c, StringBuffer buf)
  +    private void appendInCriteria(TableAlias alias, PathInfo pathInfo, InCriteria c, StringBuffer buf)
       {
  -        appendColName(c.getAttribute(), false, buf);
  +        appendColName(alias, pathInfo, buf);
           buf.append(c.getClause());
   
           if (c.getValue() instanceof Collection)
  @@ -420,65 +465,102 @@
       /**
        * Answer the SQL-Clause for a NullCriteria
        *
  +     * @param alias
  +     * @param pathInfo
        * @param c NullCriteria
  +     * @param buf
        */
  -    private void appendSQLClause(NullCriteria c, StringBuffer buf)
  +    private void appendNullCriteria(TableAlias alias, PathInfo pathInfo, NullCriteria c, StringBuffer buf)
  +    {
  +        appendColName(alias, pathInfo,buf);
  +        buf.append(c.getClause());
  +    }
  +
  +    /**
  +     * Answer the SQL-Clause for a SqlCriteria
  +     *
  +     * @param alias
  +     * @param pathInfo
  +     * @param c SqlCriteria
  +     * @param buf
  +     */
  +    private void appendSQLCriteria(SqlCriteria c, StringBuffer buf)
       {
  -        appendColName(c.getAttribute(), false, buf);
           buf.append(c.getClause());
       }
   
       /**
        * Answer the SQL-Clause for a SelectionCriteria
  +     * 
  +     * @param alias
  +     * @param pathInfo
        * @param c SelectionCriteria
  +     * @param buf
        */
  -    protected void appendSQLClause(SelectionCriteria c, StringBuffer buf)
  +    protected void appendSelectionCriteria(TableAlias alias, PathInfo pathInfo, SelectionCriteria c, StringBuffer buf)
       {
           if (c instanceof FieldCriteria)
           {
  -            appendSQLClause((FieldCriteria) c, buf);
  +            appendFieldCriteria(alias, pathInfo,(FieldCriteria) c, buf);
           }
           else if (c instanceof ColumnCriteria)
           {
  -            appendSQLClause((ColumnCriteria) c, buf);
  +            appendColumnCriteria(alias, pathInfo,(ColumnCriteria) c, buf);
           }
           else if (c instanceof NullCriteria)
           {
  -            appendSQLClause((NullCriteria) c, buf);
  +            appendNullCriteria(alias, pathInfo, (NullCriteria) c, buf);
           }
           else if (c instanceof BetweenCriteria)
           {
  -            appendSQLClause((BetweenCriteria) c, buf);
  +            appendBetweenCriteria(alias, pathInfo,(BetweenCriteria) c, buf);
           }
           else if (c instanceof InCriteria)
           {
  -            appendSQLClause((InCriteria) c, buf);
  +            appendInCriteria(alias, pathInfo, (InCriteria) c, buf);
           }
           else if (c instanceof SqlCriteria)
           {
  -            appendSQLClause((SqlCriteria) c, buf);
  +            appendSQLCriteria((SqlCriteria) c, buf);
           }
           else if (c instanceof ExistsCriteria)
           {
  -            appendSQLClause((ExistsCriteria) c, buf);
  +            appendExistsCriteria((ExistsCriteria) c, buf);
           }
           else
  -        {
  -            appendColName(c.getAttribute(), false, buf);
  +        {            
  +            appendColName(alias, pathInfo, buf);
               buf.append(c.getClause());
  -            appendParameter(c.getValue(), buf);
  -        }
  +            appendParameter(c.getValue(), buf);      
  +        }   
       }
   
       /**
  -     * Answer the SQL-Clause for a SqlCriteria
  -     *
  -     * @param c SqlCriteria
  +     * Answer the SQL-Clause for a SelectionCriteria
  +     * If the Criteria references a class with extents an OR-Clause is
  +     * added for each extent
  +     * @param c SelectionCriteria
        */
  -    private void appendSQLClause(SqlCriteria c, StringBuffer buf)
  +    protected void appendSQLClause(SelectionCriteria c, StringBuffer buf)
       {
  -        buf.append(c.getClause());
  +        AttributeInfo attrInfo = getAttributeInfo(c.getAttribute(), false);
  +        TableAlias alias = attrInfo.tableAlias;
  +        
  +        appendSelectionCriteria(alias, attrInfo.pathInfo, c, buf);
  +
  +        if (alias != null)
  +        {
  +            c.setNumberOfExtentsToBind(alias.extents.size());
  +            Iterator iter = alias.iterateExtents();
  +            while (iter.hasNext())
  +            {
  +                buf.append(" OR ");
  +                appendSelectionCriteria((TableAlias) iter.next(), attrInfo.pathInfo, c, buf);
  +            }
  +        }
  +
       }
  +    
   
       /**
        * Append the Parameter
  @@ -601,6 +683,14 @@
                       curr = createTableAlias(cld, attrPath);
                       join = new Join(prev, prevKeys, curr, keys, useOuterJoins, attr);
                       prev.addJoin(join);
  +                    
  +                    // BRJ : add outer joins for extents
  +                    for (int j=0;j < curr.extents.size(); j++)
  +                    {
  +                        TableAlias extAlias = (TableAlias)curr.extents.get(j);
  +                        Join extJoin = new Join(prev, prevKeys, extAlias, keys, true, attr);
  +                        prev.addJoin(extJoin);
  +                    }
                   }
   
                   prev = curr;
  @@ -618,15 +708,20 @@
       private TableAlias createTableAlias(ClassDescriptor cld, String path)
       {
           TableAlias alias;
  -
  +        boolean lookForExtents = false;
  + 
           if (cld.isAbstract())
           {
               getLogger().warn("Creating TableAlias for abstract ClassDescriptor: " + cld.getClassNameOfObject());
           }
  +     
  +        if (!cld.getExtentClasses().isEmpty() && path.length() > 0)
  +        {
  +            lookForExtents = true;
  +        } 
   
  -        alias = new TableAlias(cld, "A" + m_pathToAlias.size());
  +        alias = new TableAlias(cld, "A" + m_pathToAlias.size(), lookForExtents);
           m_pathToAlias.put(path, alias);
  -
           return alias;
       }
   
  @@ -841,13 +936,15 @@
           {
               buf.append(" INNER JOIN ");
           }
  +        
           buf.append(join.right.table);
           buf.append(" ");
           buf.append(join.right.alias);
           buf.append(" ON ");
           join.appendJoinEqualities(buf);
  +              
           appendTableWithJoins(join.right, where, buf);
  -    }
  +    }    
   
       /**
        * Appends to the statement columns if they are not found among the existingColumns.
  @@ -924,7 +1021,7 @@
           if (sepPos >= 0)
           {
               pathName = SqlHelper.cleanPath(name);
  -            getTableAlias(pathName.substring(0, sepPos), false);
  +            getTableAlias(pathName.substring(0, sepPos), false); 
           }
   
       }
  @@ -1041,14 +1138,24 @@
       //-----------------------------------------------------------------
   
       /**
  +     * This class is a helper to return TableAlias and PathInfo
  +     */
  +    static final class AttributeInfo
  +    {
  +        TableAlias tableAlias;
  +        PathInfo pathInfo;
  +    }
  +    
  +    /**
        * This class represents one table (possibly with alias) in the SQL query
        */
  -    static class TableAlias
  +    static final class TableAlias
       {
           final ClassDescriptor cld; // Is null for indirection table of M:N relation
           final String table;
           final String alias;
  -        private HashSet joins;
  +        private List extents = new ArrayList();
  +        private List joins;
   
           TableAlias(String table, String alias)
           {
  @@ -1059,16 +1166,44 @@
   
           TableAlias(ClassDescriptor cld, String alias)
           {
  -            this.cld = cld;
  -            this.table = cld.getFullTableName();
  -            this.alias = alias;
  +            this(cld, alias, false);
  +        }
  +
  +		TableAlias(ClassDescriptor cld, String alias, boolean lookForExtents)
  +		{
  +			this.cld = cld;
  +			this.table = cld.getFullTableName();
  +			this.alias = alias;
  +
  +            // BRJ : build alias for extents
  +			if (lookForExtents)
  +			{
  +				List ext = cld.getRepository().getConcreteSubclassesOf(cld.getClassOfObject());
  +				ClassDescriptor cd;
  +
  +				for (int i = 0; i < ext.size(); i++)
  +				{
  +					cd = cld.getRepository().getDescriptorFor((Class) ext.get(i));
  +					extents.add(new TableAlias(cd, alias + "E" + i, false));
  +				}
  +			}
  +		}
  +
  +        public boolean hasExtents()
  +        {
  +            return (!extents.isEmpty());
  +        }
  +
  +        public Iterator iterateExtents()
  +        {
  +            return extents.iterator();
           }
   
           void addJoin(Join join)
           {
               if (joins == null)
               {
  -                joins = new HashSet();
  +                joins = new ArrayList();
               }
               joins.add(join);
           }
  @@ -1167,7 +1302,7 @@
       /**
        * This class represents join between two TableAliases
        */
  -    class Join
  +    final class Join
       {
           final TableAlias left;
           final String[] leftKeys;
  
  
  
  1.9       +39 -69    jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlDeleteByQuery.java
  
  Index: SqlDeleteByQuery.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlDeleteByQuery.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- SqlDeleteByQuery.java	5 Jan 2003 09:25:33 -0000	1.8
  +++ SqlDeleteByQuery.java	19 Jan 2003 11:50:57 -0000	1.9
  @@ -54,14 +54,12 @@
    * <http://www.apache.org/>.
    */
   
  -import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  -import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
   import org.apache.ojb.broker.platforms.Platform;
   import org.apache.ojb.broker.query.Criteria;
   import org.apache.ojb.broker.query.Query;
  -import org.apache.ojb.broker.util.SqlHelper;
  +import org.apache.ojb.broker.util.SqlHelper.PathInfo;
   import org.apache.ojb.broker.util.logging.Logger;
   
   /**
  @@ -99,70 +97,42 @@
   		return stmt.toString();
   	}
   
  -	/**
  -	 * Answer the appropriate ColumnName <br>
  -	 * if a FIELDDESCRIPTOR is found for the Criteria the colName is taken from
  -	 * there otherwise its taken from Criteria. <br>
  -	 * field names in functions (ie: sum(name) ) are tried to resolve
  -	 * ie: name from FIELDDESCRIPTOR , UPPER(name_test) from Criteria<br>
  -	 * also resolve pathExpression adress.city or owner.konti.saldo
  -	 */
  -	protected void appendColName(String attr, boolean useOuterJoins, StringBuffer buf)
  -	{
  -		FieldDescriptor fld = null;
  -        SqlHelper.PathInfo pi = SqlHelper.splitPath(attr);
  -        String functionName = pi.function;
  -        String colName = pi.column;
  -		int sp;
  -
  -		sp = colName.lastIndexOf(".");
  -		if (sp == -1)
  -		{
  -			fld = getRoot().cld.getFieldDescriptorByName(colName);
  -			if (fld == null)
  -			{
  -				/**
  -				 * MBAIRD
  -				 * possible we've referred to an object not by key, ie is_undefined(obj) instead of
  -				 * is_undefined(obj.pkField)
  -				 * I don't know how to join on multiple FK fields, so check the first one.
  -				 */
  -				ObjectReferenceDescriptor ord = getRoot().cld.getObjectReferenceDescriptorByName(colName);
  -				if (ord != null)
  -				{
  -					FieldDescriptor[] fk = ord.getForeignKeyFieldDescriptors(getRoot().cld);
  -					if (fk.length > 0)
  -					{
  -						fld = fk[0];
  -					}
  -				}
  -			}
  -		}
  -		else
  -		{
  -			// joins not supported for delete
  -			throw new PersistenceBrokerException("joins not supported for delete:" + colName);
  -		}
  -
  -		if (functionName != null) // rebuild function
  -		{
  -			buf.append(functionName);
  -		}
  -
  -		if (fld != null)
  -		{
  -			// not aliases for delete
  -			buf.append(fld.getColumnName());
  -		}
  -		else
  -		{
  -			buf.append(colName);
  -		}
  -
  -		if (functionName != null) // rebuild function
  -		{
  -			buf.append(")");
  -		}
  -	}
  +    /**
  +     * Add the Column to the StringBuffer <br>
  +     * if a FieldDescriptor is found for the Criteria the colName is taken from
  +     * there otherwise its taken from Criteria. <br>
  +     * @param alias
  +     * @param pathInfo
  +     * @param buf
  +     */
  +    protected void appendColName(TableAlias alias, PathInfo pathInfo, StringBuffer buf)
  +    {
  +        FieldDescriptor fld = getField(alias, pathInfo);
  +        String functionName = pathInfo.function;
  +        String colName = pathInfo.column;
  +
  +        
  +        if (functionName != null) // rebuild function contains (
  +        {
  +            buf.append(functionName);
  +        }
  +
  +        if (fld != null)
  +        {
  +            // BRJ : No alias for delete
  +            // buf.append(alias.alias);
  +            // buf.append(".");
  +            buf.append(fld.getColumnName());
  +        }
  +        else
  +        {
  +            buf.append(colName);
  +        }
  +
  +        if (functionName != null) // rebuild function
  +        {
  +            buf.append(")");
  +        }
  +    }
   
   }
  
  
  
  1.19      +42 -18    jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
  
  Index: StatementManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- StatementManager.java	16 Jan 2003 22:16:15 -0000	1.18
  +++ StatementManager.java	19 Jan 2003 11:50:58 -0000	1.19
  @@ -447,28 +447,52 @@
                   else
                   {
                       SelectionCriteria c = (SelectionCriteria) o;
  +                    
  +                    // BRJ : bind once for the criterion's main class 
  +                    param = bindSelectionCriteria(stmt, param, c, cld);
   
  -                    if (c instanceof NullCriteria)
  -                        param = bindStatement(stmt, param, (NullCriteria) c);
  -                    else if (c instanceof BetweenCriteria)
  -                        param = bindStatement(stmt, param, (BetweenCriteria) c, cld);
  -                    else if (c instanceof InCriteria)
  -                        param = bindStatement(stmt, param, (InCriteria) c, cld);
  -                    else if (c instanceof SqlCriteria)
  -                        param = bindStatement(stmt, param, (SqlCriteria) c);
  -                    else if (c instanceof FieldCriteria)
  -                        param = bindStatement(stmt, param, (FieldCriteria) c);
  -                    else if (c instanceof ColumnCriteria)
  -                        param = bindStatement(stmt, param, (ColumnCriteria) c);
  -                    else if (c instanceof ExistsCriteria)
  -                        param = bindStatement(stmt, param, (ExistsCriteria) c, cld);
  -                    else
  -                        param = bindStatement(stmt, param, c, cld);
  +                    // BRJ : and once for each extent 
  +                    for (int i = 0; i < c.getNumberOfExtentsToBind(); i++)
  +                    {
  +                        param = bindSelectionCriteria(stmt, param, c, cld);
  +                    }
                   }
               }
           }
           return param;
       }
  +
  +    /**
  +     * bind SelectionCriteria
  +     * @param stmt the PreparedStatement
  +     * @param index the position of the parameter to bind
  +     * @param crit the Criteria containing the parameter
  +     * @param cld the ClassDescriptor
  +     * @return next index for PreparedStatement
  +     */
  +    private int bindSelectionCriteria(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld)
  +            throws SQLException
  +    {
  +        if (crit instanceof NullCriteria)
  +            index = bindStatement(stmt, index, (NullCriteria) crit);
  +        else if (crit instanceof BetweenCriteria)
  +            index = bindStatement(stmt, index, (BetweenCriteria) crit, cld);
  +        else if (crit instanceof InCriteria)
  +            index = bindStatement(stmt, index, (InCriteria) crit, cld);
  +        else if (crit instanceof SqlCriteria)
  +            index = bindStatement(stmt, index, (SqlCriteria) crit);
  +        else if (crit instanceof FieldCriteria)
  +            index = bindStatement(stmt, index, (FieldCriteria) crit);
  +        else if (crit instanceof ColumnCriteria)
  +            index = bindStatement(stmt, index, (ColumnCriteria) crit);
  +        else if (crit instanceof ExistsCriteria)
  +            index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
  +        else
  +            index = bindStatement(stmt, index, crit, cld);
  +
  +        return index;
  +    }
  +
   
       /**
        * binds the values of the object obj to the statements parameters