[hibernate-commits] Hibernate SVN: r11081 - in branches/Branch_3_2/Hibernate3: src/org/hibernate/hql/classic and 9 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jan 23 11:31:13 EST 2007


Author: steve.ebersole at jboss.com
Date: 2007-01-23 11:31:13 -0500 (Tue, 23 Jan 2007)
New Revision: 11081

Added:
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/DialectFunctionalTestsSuite.java
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/SQLFunctionsInterSystemsTest.java
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.hbm.xml
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.java
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/DialectUnitTestsSuite.java
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/AbstractLockHintTest.java
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SQLServerLockHintsTest.java
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SybaseLockHintsTest.java
Removed:
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/cache/
Modified:
   branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Dialect.java
   branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java
   branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java
   branches/Branch_3_2/Hibernate3/src/org/hibernate/hql/classic/QueryTranslatorImpl.java
   branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/AbstractEntityJoinWalker.java
   branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java
   branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
   branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java
Log:
HHH-1889 : LockModes + Sybase / SQL Server

Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Dialect.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Dialect.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/Dialect.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -38,6 +38,7 @@
 import org.hibernate.sql.ANSIJoinFragment;
 import org.hibernate.sql.CaseFragment;
 import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.ForUpdateFragment;
 import org.hibernate.type.Type;
 import org.hibernate.util.ReflectHelper;
 import org.hibernate.util.StringHelper;
@@ -901,7 +902,24 @@
 		return tableName;
 	}
 
+	/**
+	 * Modifies the given SQL by applying the appropriate updates for the specified
+	 * lock modes and key columns.
+	 * <p/>
+	 * The behavior here is that of an ANSI SQL <tt>SELECT FOR UPDATE</tt>.  This
+	 * method is really intended to allow dialects which do not support
+	 * <tt>SELECT FOR UPDATE</tt> to achieve this in their own fashion.
+	 *
+	 * @param sql the SQL string to modify
+	 * @param aliasedLockModes a map of lock modes indexed by aliased table names.
+	 * @param keyColumnNames a map of key columns indexed by aliased table names.
+	 * @return the modified SQL string.
+	 */
+	public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
+		return sql + new ForUpdateFragment( this, aliasedLockModes, keyColumnNames ).toFragmentString();
+	}
 
+
 	// temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 	/**

Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -86,7 +86,7 @@
 	}
 
 	public String appendLockHint(LockMode mode, String tableName) {
-		if ( mode.greaterThan(LockMode.READ) ) {
+		if ( mode.greaterThan( LockMode.READ ) ) {
 			// does this need holdlock also? : return tableName + " with (updlock, rowlock, holdlock)";
 			return tableName + " with (updlock, rowlock)";
 		}

Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/dialect/SybaseDialect.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -5,6 +5,8 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
+import java.util.Map;
+import java.util.Iterator;
 
 import org.hibernate.Hibernate;
 import org.hibernate.LockMode;
@@ -133,7 +135,7 @@
 	}
 
 	public String appendLockHint(LockMode mode, String tableName) {
-		if ( mode.greaterThan(LockMode.READ) ) {
+		if ( mode.greaterThan( LockMode.READ ) ) {
 			return tableName + " holdlock";
 		}
 		else {
@@ -141,6 +143,41 @@
 		}
 	}
 
+	public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
+		Iterator itr = aliasedLockModes.entrySet().iterator();
+		StringBuffer buffer = new StringBuffer( sql );
+		int correction = 0;
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final LockMode lockMode = ( LockMode ) entry.getValue();
+			if ( lockMode.greaterThan( LockMode.READ ) ) {
+				final String alias = ( String ) entry.getKey();
+				int start = -1, end = -1;
+				if ( sql.endsWith( " " + alias ) ) {
+					start = ( sql.length() - alias.length() ) + correction;
+					end = start + alias.length();
+				}
+				else {
+					int position = sql.indexOf( " " + alias + " " );
+					if ( position <= -1 ) {
+						position = sql.indexOf( " " + alias + "," );
+					}
+					if ( position > -1 ) {
+						start = position + correction + 1;
+						end = start + alias.length();
+					}
+				}
+
+				if ( start > -1 ) {
+					final String lockHint = appendLockHint( lockMode, alias );
+					buffer.replace( start, end, lockHint );
+					correction += ( lockHint.length() - alias.length() );
+				}
+			}
+		}
+		return buffer.toString();
+	}
+
 	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
 		return col; // sql server just returns automatically
 	}

Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/hql/classic/QueryTranslatorImpl.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/hql/classic/QueryTranslatorImpl.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/hql/classic/QueryTranslatorImpl.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -17,12 +17,12 @@
 import org.apache.commons.collections.SequencedHashMap;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
 import org.hibernate.MappingException;
 import org.hibernate.QueryException;
 import org.hibernate.ScrollableResults;
-import org.hibernate.hql.ParameterTranslations;
 import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.JoinSequence;
 import org.hibernate.engine.QueryParameters;
@@ -33,6 +33,7 @@
 import org.hibernate.hql.FilterTranslator;
 import org.hibernate.hql.HolderInstantiator;
 import org.hibernate.hql.NameGenerator;
+import org.hibernate.hql.ParameterTranslations;
 import org.hibernate.impl.IteratorImpl;
 import org.hibernate.loader.BasicLoader;
 import org.hibernate.persister.collection.CollectionPersister;
@@ -40,7 +41,6 @@
 import org.hibernate.persister.entity.Loadable;
 import org.hibernate.persister.entity.PropertyMapping;
 import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.ForUpdateFragment;
 import org.hibernate.sql.JoinFragment;
 import org.hibernate.sql.QuerySelect;
 import org.hibernate.transform.ResultTransformer;
@@ -56,8 +56,7 @@
  * An instance of <tt>QueryTranslator</tt> translates a Hibernate
  * query string to SQL.
  */
-public class QueryTranslatorImpl extends BasicLoader
-		implements FilterTranslator {
+public class QueryTranslatorImpl extends BasicLoader implements FilterTranslator {
 
 	private static final String[] NO_RETURN_ALIASES = new String[] {};
 
@@ -121,6 +120,13 @@
 
 	/**
 	 * Construct a query translator
+	 *
+	 * @param queryIdentifier A unique identifier for the query of which this
+	 * translation is part; typically this is the original, user-supplied query string.
+	 * @param queryString The "preprocessed" query string; at the very least
+	 * already processed by {@link org.hibernate.hql.QuerySplitter}.
+	 * @param enabledFilters Any enabled filters.
+	 * @param factory The session factory.
 	 */
 	public QueryTranslatorImpl(
 			String queryIdentifier,
@@ -134,7 +140,11 @@
 	}
 
 	/**
-	 * Construct a query translator
+	 * Construct a query translator; this form used internally.
+	 *
+	 * @param queryString The query string to process.
+	 * @param enabledFilters Any enabled filters.
+	 * @param factory The session factory.
 	 */
 	public QueryTranslatorImpl(
 	        String queryString,
@@ -144,10 +154,16 @@
 	}
 
 	/**
-	 * Compile a subquery
+	 * Compile a subquery.
+	 *
+	 * @param superquery The containing query of the query to be compiled.
+	 *
+	 * @throws org.hibernate.MappingException Indicates problems resolving
+	 * things referenced in the query.
+	 * @throws org.hibernate.QueryException Generally some form of syntatic
+	 * failure.
 	 */
-	void compile(QueryTranslatorImpl superquery)
-			throws QueryException, MappingException {
+	void compile(QueryTranslatorImpl superquery) throws QueryException, MappingException {
 		this.tokenReplacements = superquery.tokenReplacements;
 		this.superQuery = superquery;
 		this.shallowQuery = true;
@@ -160,8 +176,9 @@
 	 * Compile a "normal" query. This method may be called multiple
 	 * times. Subsequent invocations are no-ops.
 	 */
-	public synchronized void compile(Map replacements, boolean scalar)
-			throws QueryException, MappingException {
+	public synchronized void compile(
+			Map replacements,
+			boolean scalar) throws QueryException, MappingException {
 		if ( !compiled ) {
 			this.tokenReplacements = replacements;
 			this.shallowQuery = scalar;
@@ -173,8 +190,10 @@
 	 * Compile a filter. This method may be called multiple
 	 * times. Subsequent invocations are no-ops.
 	 */
-	public synchronized void compile(String collectionRole, Map replacements, boolean scalar)
-			throws QueryException, MappingException {
+	public synchronized void compile(
+			String collectionRole,
+			Map replacements,
+			boolean scalar) throws QueryException, MappingException {
 
 		if ( !isCompiled() ) {
 			addFromAssociation( "this", collectionRole );
@@ -184,6 +203,11 @@
 
 	/**
 	 * Compile the query (generate the SQL).
+	 *
+	 * @throws org.hibernate.MappingException Indicates problems resolving
+	 * things referenced in the query.
+	 * @throws org.hibernate.QueryException Generally some form of syntatic
+	 * failure.
 	 */
 	private void compile() throws QueryException, MappingException {
 
@@ -245,7 +269,7 @@
 	public Type[] getReturnTypes() {
 		return actualReturnTypes;
 	}
-	
+
 	public String[] getReturnAliases() {
 		// return aliases not supported in classic translator!
 		return NO_RETURN_ALIASES;
@@ -917,11 +941,11 @@
 
 		}
 		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert( 
+			throw JDBCExceptionHelper.convert(
 					getFactory().getSQLExceptionConverter(),
 					sqle,
 					"could not execute query using iterate",
-					getSQLString() 
+					getSQLString()
 				);
 		}
 
@@ -1031,7 +1055,7 @@
 					keyColumnNames.put( names[i], persisters[i].getIdentifierColumnNames() );
 				}
 			}
-			result = sql + new ForUpdateFragment( dialect, aliasedLockModes, keyColumnNames ).toFragmentString();
+			result = dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
 		}
 		logQuery( queryString, result );
 		return result;

Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/AbstractEntityJoinWalker.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/AbstractEntityJoinWalker.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/AbstractEntityJoinWalker.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -20,14 +20,14 @@
 /**
  * Abstract walker for walkers which begin at an entity (criteria
  * queries and entity loaders).
- * 
+ *
  * @author Gavin King
  */
 public abstract class AbstractEntityJoinWalker extends JoinWalker {
 
 	private final OuterJoinLoadable persister;
 	private String alias;
-	
+
 	public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters) {
 		super( factory, enabledFilters );
 		this.persister = persister;
@@ -39,25 +39,25 @@
 		final String orderByString,
 		final LockMode lockMode)
 	throws MappingException {
-		
+
 		walkEntityTree( persister, getAlias() );
-		
+
 		List allAssociations = new ArrayList();
 		allAssociations.addAll(associations);
-		allAssociations.add( new OuterJoinableAssociation( 
+		allAssociations.add( new OuterJoinableAssociation(
 				persister.getEntityType(),
-				null, 
-				null, 
-				alias, 
-				JoinFragment.LEFT_OUTER_JOIN, 
+				null,
+				null,
+				alias,
+				JoinFragment.LEFT_OUTER_JOIN,
 				getFactory(),
 				CollectionHelper.EMPTY_MAP
 			) );
-		
+
 		initPersisters(allAssociations, lockMode);
 		initStatementString( whereString, orderByString, lockMode);
 	}
-	
+
 	protected final void initProjection(
 		final String projectionString,
 		final String whereString,
@@ -77,38 +77,37 @@
 	throws MappingException {
 		initStatementString(null, condition, orderBy, "", lockMode);
 	}
-	
+
 	private void initStatementString(
 			final String projection,
 			final String condition,
 			final String orderBy,
 			final String groupBy,
-			final LockMode lockMode)
-		throws MappingException {
+			final LockMode lockMode) throws MappingException {
 
 		final int joins = countEntityPersisters( associations );
-		suffixes = BasicLoader.generateSuffixes( joins+1 );
+		suffixes = BasicLoader.generateSuffixes( joins + 1 );
 
 		JoinFragment ojf = mergeOuterJoins( associations );
-		
+
 		Select select = new Select( getDialect() )
-			.setLockMode(lockMode)
-			.setSelectClause(
-					projection==null ? 
-							persister.selectFragment( alias, suffixes[joins] ) + selectString(associations) : 
-							projection
-			)
-			.setFromClause(
-				persister.fromTableFragment(alias) +
-				persister.fromJoinFragment(alias, true, true)
-			)
-			.setWhereClause(condition)
-			.setOuterJoins(
-				ojf.toFromFragmentString(),
-				ojf.toWhereFragmentString() + getWhereFragment()
-			)
-			.setOrderByClause( orderBy( associations, orderBy ) )
-			.setGroupByClause(groupBy);
+				.setLockMode( lockMode )
+				.setSelectClause(
+						projection == null ?
+								persister.selectFragment( alias, suffixes[joins] ) + selectString( associations ) :
+								projection
+				)
+				.setFromClause(
+						getDialect().appendLockHint( lockMode, persister.fromTableFragment( alias ) ) +
+								persister.fromJoinFragment( alias, true, true )
+				)
+				.setWhereClause( condition )
+				.setOuterJoins(
+						ojf.toFromFragmentString(),
+						ojf.toWhereFragmentString() + getWhereFragment()
+				)
+				.setOrderByClause( orderBy( associations, orderBy ) )
+				.setGroupByClause( groupBy );
 
 		if ( getFactory().getSettings().isCommentsEnabled() ) {
 			select.setComment( getComment() );
@@ -116,10 +115,8 @@
 		sql = select.toStatementString();
 	}
 
-	/**
-	 * Don't bother with the discriminator, unless overridded by subclass
-	 */
 	protected String getWhereFragment() throws MappingException {
+		// here we do not bother with the discriminator.
 		return persister.whereJoinFragment(alias, true, true);
 	}
 

Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -21,7 +21,6 @@
 import org.hibernate.loader.OuterJoinLoader;
 import org.hibernate.persister.entity.Loadable;
 import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.sql.ForUpdateFragment;
 import org.hibernate.transform.ResultTransformer;
 import org.hibernate.type.Type;
 
@@ -33,8 +32,8 @@
  */
 public class CriteriaLoader extends OuterJoinLoader {
 
-	//TODO: this class depends directly upon CriteriaImpl, 
-	//      in the impl package ... add a CriteriaImplementor 
+	//TODO: this class depends directly upon CriteriaImpl,
+	//      in the impl package ... add a CriteriaImplementor
 	//      interface
 
 	//NOTE: unlike all other Loaders, this one is NOT
@@ -48,49 +47,49 @@
 	private final String[] userAliases;
 
 	public CriteriaLoader(
-			final OuterJoinLoadable persister, 
-			final SessionFactoryImplementor factory, 
-			final CriteriaImpl criteria, 
+			final OuterJoinLoadable persister,
+			final SessionFactoryImplementor factory,
+			final CriteriaImpl criteria,
 			final String rootEntityName,
 			final Map enabledFilters)
 	throws HibernateException {
 		super(factory, enabledFilters);
 
 		translator = new CriteriaQueryTranslator(
-				factory, 
-				criteria, 
-				rootEntityName, 
+				factory,
+				criteria,
+				rootEntityName,
 				CriteriaQueryTranslator.ROOT_SQL_ALIAS
 			);
 
 		querySpaces = translator.getQuerySpaces();
-		
+
 		CriteriaJoinWalker walker = new CriteriaJoinWalker(
-				persister, 
+				persister,
 				translator,
-				factory, 
-				criteria, 
-				rootEntityName, 
+				factory,
+				criteria,
+				rootEntityName,
 				enabledFilters
 			);
 
 		initFromWalker(walker);
-		
+
 		userAliases = walker.getUserAliases();
 		resultTypes = walker.getResultTypes();
 
 		postInstantiate();
 
 	}
-	
-	public ScrollableResults scroll(SessionImplementor session, ScrollMode scrollMode) 
+
+	public ScrollableResults scroll(SessionImplementor session, ScrollMode scrollMode)
 	throws HibernateException {
 		QueryParameters qp = translator.getQueryParameters();
 		qp.setScrollMode(scrollMode);
 		return scroll(qp, resultTypes, null, session);
 	}
 
-	public List list(SessionImplementor session) 
+	public List list(SessionImplementor session)
 	throws HibernateException {
 		return list( session, translator.getQueryParameters(), querySpaces, resultTypes );
 
@@ -121,33 +120,28 @@
 		return querySpaces;
 	}
 
-	protected String applyLocks(String sqlSelectString, Map lockModes, Dialect dialect) 
-	throws QueryException {
-		
-		if ( lockModes==null || lockModes.size()==0 ) {
+	protected String applyLocks(String sqlSelectString, Map lockModes, Dialect dialect) throws QueryException {
+		if ( lockModes == null || lockModes.isEmpty() ) {
 			return sqlSelectString;
 		}
-		else {
-			Map keyColumnNames = null;
-			Loadable[] persisters = getEntityPersisters();
-			String[] entityAliases = getAliases();
-			if ( dialect.forUpdateOfColumns() ) {
-				keyColumnNames = new HashMap();
-				for ( int i=0; i<entityAliases.length; i++ ) {
-					keyColumnNames.put( 
-							entityAliases[i], 
-							persisters[i].getIdentifierColumnNames() 
-						);
-				}
+
+		Map keyColumnNames = null;
+		Loadable[] persisters = getEntityPersisters();
+		String[] entityAliases = getAliases();
+		if ( dialect.forUpdateOfColumns() ) {
+			keyColumnNames = new HashMap();
+			for ( int i=0; i<entityAliases.length; i++ ) {
+				keyColumnNames.put( entityAliases[i], persisters[i].getIdentifierColumnNames() );
 			}
-			return sqlSelectString + 
-				new ForUpdateFragment(dialect, lockModes, keyColumnNames).toFragmentString();
 		}
+		return dialect.applyLocksToSql( sqlSelectString, lockModes, keyColumnNames );
 	}
 
 	protected LockMode[] getLockModes(Map lockModes) {
 		final String[] entityAliases = getAliases();
-		if (entityAliases==null) return null;
+		if ( entityAliases == null ) {
+			return null;
+		}
 		final int size = entityAliases.length;
 		LockMode[] lockModesArray = new LockMode[size];
 		for ( int i=0; i<size; i++ ) {
@@ -160,10 +154,9 @@
 	protected boolean isSubselectLoadingEnabled() {
 		return hasSubselectLoadableCollections();
 	}
-	
+
 	protected List getResultList(List results, ResultTransformer resultTransformer) {
-		return translator.getRootCriteria().getResultTransformer()
-				.transformList(results);
+		return translator.getRootCriteria().getResultTransformer().transformList( results );
 	}
 
 }

Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -9,9 +9,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
 import org.hibernate.QueryException;
@@ -33,7 +30,6 @@
 import org.hibernate.persister.collection.QueryableCollection;
 import org.hibernate.persister.entity.Loadable;
 import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.ForUpdateFragment;
 import org.hibernate.transform.ResultTransformer;
 import org.hibernate.type.EntityType;
 import org.hibernate.type.Type;
@@ -46,11 +42,11 @@
  */
 public class QueryLoader extends BasicLoader {
 
-	private static final Log log = LogFactory.getLog( QueryLoader.class );
+	/**
+	 * The query translator that is delegating to this object.
+	 */
+	private QueryTranslatorImpl queryTranslator;
 
-	private final QueryTranslatorImpl queryTranslator;
-	private final boolean isCollectionFilter;
-
 	private Queryable[] entityPersisters;
 	private String[] entityAliases;
 	private String[] sqlAliases;
@@ -61,6 +57,7 @@
 
 	private boolean hasScalars;
 	private String[][] scalarColumnNames;
+	//private Type[] sqlResultTypes;
 	private Type[] queryReturnTypes;
 
 	private final Map sqlAliasByEntityAlias = new HashMap(8);
@@ -93,13 +90,14 @@
 	        final SelectClause selectClause) {
 		super( factory );
 		this.queryTranslator = queryTranslator;
-		this.isCollectionFilter = selectClause.getWalker().isFilter();
 		initialize( selectClause );
 		postInstantiate();
 	}
 
 	private void initialize(SelectClause selectClause) {
+
 		List fromElementList = selectClause.getFromElementsForLoad();
+
 		hasScalars = selectClause.isScalarSelect();
 		scalarColumnNames = selectClause.getColumnNames();
 		//sqlResultTypes = selectClause.getSqlResultTypes();
@@ -172,7 +170,7 @@
 			}
 		}
 
-		//NONE, because its the requested lock mode, not the actual! 
+		//NONE, because its the requested lock mode, not the actual!
 		defaultLockModes = ArrayHelper.fillArray(LockMode.NONE, size);
 
 	}
@@ -269,7 +267,7 @@
 			for ( int i = 0; i < entityAliases.length; i++ ) {
 				LockMode lockMode = (LockMode) lockModes.get( entityAliases[i] );
 				if ( lockMode == null ) {
-					//NONE, because its the requested lock mode, not the actual! 
+					//NONE, because its the requested lock mode, not the actual!
 					lockMode = LockMode.NONE;
 				}
 				lockModeArray[i] = lockMode;
@@ -278,15 +276,12 @@
 		}
 	}
 
-	protected String applyLocks(String sql, Map lockModes, Dialect dialect)
-			throws QueryException {
-
+	protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws QueryException {
 		if ( lockModes == null || lockModes.size() == 0 ) {
 			return sql;
 		}
 		else {
 			// can't cache this stuff either (per-invocation)
-
 			//we are given a map of user alias -> lock mode
 			//create a new map of sql alias -> lock mode
 			final Map aliasedLockModes = new HashMap();
@@ -311,8 +306,7 @@
 				}
 			}
 
-			return sql + new ForUpdateFragment( dialect, aliasedLockModes, keyColumnNames ).toFragmentString();
-
+			return dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
 		}
 	}
 
@@ -374,31 +368,22 @@
 
 	// --- Query translator methods ---
 
-	/**
-	 * Delegats
-	 *
-	 * @param session
-	 * @param queryParameters
-	 * @return
-	 * @throws HibernateException
-	 */
-	public List list(SessionImplementor session, QueryParameters queryParameters)
-			throws HibernateException {
+	public List list(
+			SessionImplementor session,
+			QueryParameters queryParameters) throws HibernateException {
 		checkQuery( queryParameters );
 		return list( session, queryParameters, queryTranslator.getQuerySpaces(), queryReturnTypes );
 	}
 
 	private void checkQuery(QueryParameters queryParameters) {
-		if(hasSelectNew() && queryParameters.getResultTransformer()!=null) {
-			throw new QueryException("ResultTransformer is not allowed for 'select new' queries.");
+		if ( hasSelectNew() && queryParameters.getResultTransformer() != null ) {
+			throw new QueryException( "ResultTransformer is not allowed for 'select new' queries." );
 		}
 	}
 
-	/**
-	 * Return the query results as an iterator
-	 */
-	public Iterator iterate(QueryParameters queryParameters, EventSource session)
-			throws HibernateException {
+	public Iterator iterate(
+			QueryParameters queryParameters,
+			EventSource session) throws HibernateException {
 		checkQuery( queryParameters );
 		final boolean stats = session.getFactory().getStatistics().isStatisticsEnabled();
 		long startTime = 0;

Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java	2007-01-23 16:29:18 UTC (rev 11080)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/AllTests.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -30,7 +30,8 @@
 import org.hibernate.test.cuk.CompositePropertyRefTest;
 import org.hibernate.test.cut.CompositeUserTypeTest;
 import org.hibernate.test.deletetransient.DeleteTransientEntityTest;
-import org.hibernate.test.dialect.cache.SQLFunctionsInterSystemsTest;
+import org.hibernate.test.dialect.functional.DialectFunctionalTestsSuite;
+import org.hibernate.test.dialect.unit.DialectUnitTestsSuite;
 import org.hibernate.test.discriminator.DiscriminatorTest;
 import org.hibernate.test.dynamicentity.interceptor.InterceptorDynamicEntityTest;
 import org.hibernate.test.dynamicentity.tuplizer.TuplizerDynamicEntityTest;
@@ -271,12 +272,13 @@
 			suite.addTest( AbstractCompositeIdTest.suite() );
 			suite.addTest( UtilSuite.suite() );
 			suite.addTest( AnyTypeTest.suite() );
-			suite.addTest( SQLFunctionsInterSystemsTest.suite() );
 			suite.addTest( LobSuite.suite() );
 			suite.addTest( IdentifierPropertyReferencesTest.suite() );
 			suite.addTest( DeleteTransientEntityTest.suite() );
 			suite.addTest( UserCollectionTypeTest.suite() );
 			suite.addTest( KeyManyToOneSuite.suite() );
+			suite.addTest( DialectFunctionalTestsSuite.suite() );
+			suite.addTest( DialectUnitTestsSuite.suite() );
 
 			return filter( suite );
 		}

Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/DialectFunctionalTestsSuite.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/DialectFunctionalTestsSuite.java	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/DialectFunctionalTestsSuite.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,18 @@
+package org.hibernate.test.dialect.functional;
+
+import junit.framework.TestSuite;
+
+import org.hibernate.test.dialect.functional.cache.SQLFunctionsInterSystemsTest;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class DialectFunctionalTestsSuite {
+	public static TestSuite suite() {
+		TestSuite suite = new TestSuite( "Dialect tests" );
+		suite.addTest( SQLFunctionsInterSystemsTest.suite() );
+		return suite;
+	}
+}

Copied: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/SQLFunctionsInterSystemsTest.java (from rev 10976, branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/cache/SQLFunctionsInterSystemsTest.java)
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/SQLFunctionsInterSystemsTest.java	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/SQLFunctionsInterSystemsTest.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,740 @@
+package org.hibernate.test.dialect.functional.cache;
+
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Test;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Transaction;
+import org.hibernate.classic.Session;
+import org.hibernate.dialect.Cache71Dialect;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.dialect.InterbaseDialect;
+import org.hibernate.dialect.MckoiDialect;
+import org.hibernate.dialect.MySQLDialect;
+import org.hibernate.dialect.Oracle9Dialect;
+import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.TimesTenDialect;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.test.legacy.Blobber;
+import org.hibernate.test.legacy.Broken;
+import org.hibernate.test.legacy.Fixed;
+import org.hibernate.test.legacy.Simple;
+import org.hibernate.test.legacy.Single;
+
+/**
+ * Tests for function support on CacheSQL...
+ *
+ * @author Jonathan Levinson
+ */
+public class SQLFunctionsInterSystemsTest extends DatabaseSpecificFunctionalTestCase {
+
+	private static final Log log = LogFactory.getLog(SQLFunctionsInterSystemsTest.class);
+
+	public SQLFunctionsInterSystemsTest(String name) {
+		super(name);
+	}
+
+	public String[] getMappings() {
+		return new String[] {
+				"legacy/AltSimple.hbm.xml",
+				"legacy/Broken.hbm.xml",
+				"legacy/Blobber.hbm.xml",
+				"dialect/functional/cache/TestInterSystemsFunctionsClass.hbm.xml"
+		};
+	}
+
+	public static Test suite() {
+		return new FunctionalTestClassTestSuite( SQLFunctionsInterSystemsTest.class );
+	}
+
+	public boolean appliesTo(Dialect dialect) {
+		// all these test case apply only to testing InterSystems' CacheSQL dialect
+		return dialect instanceof Cache71Dialect;
+	}
+
+	public void testDialectSQLFunctions() throws Exception {
+
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+
+		Iterator iter = s.iterate("select max(s.count) from Simple s");
+
+		if ( getDialect() instanceof MySQLDialect ) assertTrue( iter.hasNext() && iter.next()==null );
+
+		Simple simple = new Simple();
+		simple.setName("Simple Dialect Function Test");
+		simple.setAddress("Simple Address");
+		simple.setPay(new Float(45.8));
+		simple.setCount(2);
+		s.save(simple, new Long(10) );
+
+		// Test to make sure allocating an specified object operates correctly.
+		assertTrue(
+			s.find("select new org.hibernate.test.legacy.S(s.count, s.address) from Simple s").size() == 1
+		);
+
+		// Quick check the base dialect functions operate correctly
+		assertTrue(
+			s.find("select max(s.count) from Simple s").size() == 1
+		);
+		assertTrue(
+			s.find("select count(*) from Simple s").size() == 1
+		);
+
+		if ( getDialect() instanceof Cache71Dialect) {
+			// Check Oracle Dialect mix of dialect functions - no args (no parenthesis and single arg functions
+			java.util.List rset = s.find("select s.name, sysdate, floor(s.pay), round(s.pay,0) from Simple s");
+			assertNotNull("Name string should have been returned",(((Object[])rset.get(0))[0]));
+			assertNotNull("Todays Date should have been returned",(((Object[])rset.get(0))[1]));
+			assertEquals("floor(45.8) result was incorrect ", new Integer(45), ( (Object[]) rset.get(0) )[2] );
+			assertEquals("round(45.8) result was incorrect ", new Float(46), ( (Object[]) rset.get(0) )[3] );
+
+			simple.setPay(new Float(-45.8));
+			s.update(simple);
+
+			// Test type conversions while using nested functions (Float to Int).
+			rset = s.find("select abs(round(s.pay,0)) from Simple s");
+			assertEquals("abs(round(-45.8)) result was incorrect ", new Float(46), rset.get(0));
+
+			// Test a larger depth 3 function example - Not a useful combo other than for testing
+			assertTrue(
+				s.find("select floor(round(sysdate,1)) from Simple s").size() == 1
+			);
+
+			// Test the oracle standard NVL funtion as a test of multi-param functions...
+			simple.setPay(null);
+			s.update(simple);
+			Double value = (Double) s.createQuery("select mod( nvl(s.pay, 5000), 2 ) from Simple as s where s.id = 10").list().get(0);
+			assertTrue( 0 == value.intValue() );
+		}
+
+		if ( (getDialect() instanceof Cache71Dialect) ) {
+			// Test the hsql standard MOD funtion as a test of multi-param functions...
+			Double value = (Double) s.find("select MOD(s.count, 2) from Simple as s where s.id = 10" ).get(0);
+			assertTrue( 0 == value.intValue() );
+        }
+
+        /*
+        if ( (getDialect() instanceof Cache71Dialect) ) {
+            // Test the hsql standard MOD funtion as a test of multi-param functions...
+            Date value = (Date) s.find("select sysdate from Simple as s where nvl(cast(null as date), sysdate)=sysdate" ).get(0);
+            assertTrue( value.equals(new java.sql.Date(System.currentTimeMillis())));
+        }
+        */
+
+        s.delete(simple);
+		t.commit();
+		s.close();
+	}
+
+	public void testSetProperties() throws Exception {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Simple simple = new Simple();
+		simple.setName("Simple 1");
+		s.save(simple, new Long(10) );
+		Query q = s.createQuery("from Simple s where s.name=:name and s.count=:count");
+		q.setProperties(simple);
+		assertTrue( q.list().get(0)==simple );
+		//misuse of "Single" as a propertyobject, but it was the first testclass i found with a collection ;)
+		Single single = new Single() { // trivial hack to test properties with arrays.
+			String[] getStuff() { return (String[]) getSeveral().toArray(new String[getSeveral().size()]); }
+		};
+
+		List l = new ArrayList();
+		l.add("Simple 1");
+		l.add("Slimeball");
+		single.setSeveral(l);
+		q = s.createQuery("from Simple s where s.name in (:several)");
+		q.setProperties(single);
+		assertTrue( q.list().get(0)==simple );
+
+
+		q = s.createQuery("from Simple s where s.name in (:stuff)");
+		q.setProperties(single);
+		assertTrue( q.list().get(0)==simple );
+		s.delete(simple);
+		t.commit();
+		s.close();
+	}
+
+	public void testBroken() throws Exception {
+		if (getDialect() instanceof Oracle9Dialect) return;
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Broken b = new Fixed();
+		b.setId( new Long(123));
+		b.setOtherId("foobar");
+		s.save(b);
+		s.flush();
+		b.setTimestamp( new Date() );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.update(b);
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		b = (Broken) s.load( Broken.class, b );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.delete(b);
+		t.commit();
+		s.close();
+	}
+
+	public void testNothinToUpdate() throws Exception {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Simple simple = new Simple();
+		simple.setName("Simple 1");
+		s.save( simple, new Long(10) );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.update( simple, new Long(10) );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.update( simple, new Long(10) );
+		s.delete(simple);
+		t.commit();
+		s.close();
+	}
+
+	public void testCachedQuery() throws Exception {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Simple simple = new Simple();
+		simple.setName("Simple 1");
+		s.save( simple, new Long(10) );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		Query q = s.createQuery("from Simple s where s.name=?");
+		q.setCacheable(true);
+		q.setString(0, "Simple 1");
+		assertTrue( q.list().size()==1 );
+		assertTrue( q.list().size()==1 );
+		assertTrue( q.list().size()==1 );
+		q = s.createQuery("from Simple s where s.name=:name");
+		q.setCacheable(true);
+		q.setString("name", "Simple 1");
+		assertTrue( q.list().size()==1 );
+		simple = (Simple) q.list().get(0);
+
+		q.setString("name", "Simple 2");
+		assertTrue( q.list().size()==0 );
+		assertTrue( q.list().size()==0 );
+		simple.setName("Simple 2");
+		assertTrue( q.list().size()==1 );
+		assertTrue( q.list().size()==1 );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		q = s.createQuery("from Simple s where s.name=:name");
+		q.setString("name", "Simple 2");
+		q.setCacheable(true);
+		assertTrue( q.list().size()==1 );
+		assertTrue( q.list().size()==1 );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.update( simple, new Long(10) );
+		s.delete(simple);
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		q = s.createQuery("from Simple s where s.name=?");
+		q.setCacheable(true);
+		q.setString(0, "Simple 1");
+		assertTrue( q.list().size()==0 );
+		assertTrue( q.list().size()==0 );
+		t.commit();
+		s.close();
+	}
+
+	public void testCachedQueryRegion() throws Exception {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Simple simple = new Simple();
+		simple.setName("Simple 1");
+		s.save( simple, new Long(10) );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		Query q = s.createQuery("from Simple s where s.name=?");
+		q.setCacheRegion("foo");
+		q.setCacheable(true);
+		q.setString(0, "Simple 1");
+		assertTrue( q.list().size()==1 );
+		assertTrue( q.list().size()==1 );
+		assertTrue( q.list().size()==1 );
+		q = s.createQuery("from Simple s where s.name=:name");
+		q.setCacheRegion("foo");
+		q.setCacheable(true);
+		q.setString("name", "Simple 1");
+		assertTrue( q.list().size()==1 );
+		simple = (Simple) q.list().get(0);
+
+		q.setString("name", "Simple 2");
+		assertTrue( q.list().size()==0 );
+		assertTrue( q.list().size()==0 );
+		simple.setName("Simple 2");
+		assertTrue( q.list().size()==1 );
+		assertTrue( q.list().size()==1 );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.update( simple, new Long(10) );
+		s.delete(simple);
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		q = s.createQuery("from Simple s where s.name=?");
+		q.setCacheRegion("foo");
+		q.setCacheable(true);
+		q.setString(0, "Simple 1");
+		assertTrue( q.list().size()==0 );
+		assertTrue( q.list().size()==0 );
+		t.commit();
+		s.close();
+	}
+
+	public void testSQLFunctions() throws Exception {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Simple simple = new Simple();
+		simple.setName("Simple 1");
+		s.save(simple, new Long(10) );
+
+		if ( getDialect() instanceof Cache71Dialect) {
+			s.find("from Simple s where repeat('foo', 3) = 'foofoofoo'");
+			s.find("from Simple s where repeat(s.name, 3) = 'foofoofoo'");
+			s.find("from Simple s where repeat( lower(s.name), (3 + (1-1)) / 2) = 'foofoofoo'");
+		}
+
+		assertTrue(
+			s.find("from Simple s where upper( s.name ) ='SIMPLE 1'").size()==1
+		);
+		if ( !(getDialect() instanceof HSQLDialect) ) {
+			assertTrue(
+				s.find("from Simple s where not( upper( s.name ) ='yada' or 1=2 or 'foo'='bar' or not('foo'='foo') or 'foo' like 'bar' )").size()==1
+			);
+		}
+		if ( !(getDialect() instanceof MySQLDialect) && !(getDialect() instanceof SybaseDialect) && !(getDialect() instanceof MckoiDialect) && !(getDialect() instanceof InterbaseDialect) && !(getDialect() instanceof TimesTenDialect) ) { //My SQL has a funny concatenation operator
+			assertTrue(
+				s.find("from Simple s where lower( s.name || ' foo' ) ='simple 1 foo'").size()==1
+			);
+		}
+        /* + is not concat in Cache
+        if ( (getDialect() instanceof Cache71Dialect) ) {
+			assertTrue(
+				s.find("from Simple s where lower( cons.name ' foo' ) ='simple 1 foo'").size()==1
+			);
+		}
+		*/
+		if ( (getDialect() instanceof Cache71Dialect) ) {
+			assertTrue(
+				s.find("from Simple s where lower( concat(s.name, ' foo') ) ='simple 1 foo'").size()==1
+			);
+		}
+
+		Simple other = new Simple();
+		other.setName("Simple 2");
+		other.setCount(12);
+		simple.setOther(other);
+		s.save( other, new Long(20) );
+		//s.find("from Simple s where s.name ## 'cat|rat|bag'");
+		assertTrue(
+			s.find("from Simple s where upper( s.other.name ) ='SIMPLE 2'").size()==1
+		);
+		assertTrue(
+			s.find("from Simple s where not ( upper( s.other.name ) ='SIMPLE 2' )").size()==0
+		);
+		assertTrue(
+			s.find("select distinct s from Simple s where ( ( s.other.count + 3 ) = (15*2)/2 and s.count = 69) or ( ( s.other.count + 2 ) / 7 ) = 2").size()==1
+		);
+		assertTrue(
+			s.find("select s from Simple s where ( ( s.other.count + 3 ) = (15*2)/2 and s.count = 69) or ( ( s.other.count + 2 ) / 7 ) = 2 order by s.other.count").size()==1
+		);
+		Simple min = new Simple();
+		min.setCount(-1);
+		s.save(min, new Long(30) );
+		if ( ! (getDialect() instanceof MySQLDialect) && ! (getDialect() instanceof HSQLDialect) ) { //My SQL has no subqueries
+			assertTrue(
+				s.find("from Simple s where s.count > ( select min(sim.count) from Simple sim )").size()==2
+			);
+			t.commit();
+			t = s.beginTransaction();
+			assertTrue(
+				s.find("from Simple s where s = some( select sim from Simple sim where sim.count>=0 ) and s.count >= 0").size()==2
+			);
+			assertTrue(
+				s.find("from Simple s where s = some( select sim from Simple sim where sim.other.count=s.other.count ) and s.other.count > 0").size()==1
+			);
+		}
+
+		Iterator iter = s.iterate("select sum(s.count) from Simple s group by s.count having sum(s.count) > 10");
+		assertTrue( iter.hasNext() );
+		assertEquals( new Long(12), iter.next() );
+		assertTrue( !iter.hasNext() );
+		if ( ! (getDialect() instanceof MySQLDialect) ) {
+			iter = s.iterate("select s.count from Simple s group by s.count having s.count = 12");
+			assertTrue( iter.hasNext() );
+		}
+
+		s.iterate("select s.id, s.count, count(t), max(t.date) from Simple s, Simple t where s.count = t.count group by s.id, s.count order by s.count");
+
+		Query q = s.createQuery("from Simple s");
+		q.setMaxResults(10);
+		assertTrue( q.list().size()==3 );
+		q = s.createQuery("from Simple s");
+		q.setMaxResults(1);
+		assertTrue( q.list().size()==1 );
+		q = s.createQuery("from Simple s");
+		assertTrue( q.list().size()==3 );
+		q = s.createQuery("from Simple s where s.name = ?");
+		q.setString(0, "Simple 1");
+		assertTrue( q.list().size()==1 );
+		q = s.createQuery("from Simple s where s.name = ? and upper(s.name) = ?");
+		q.setString(1, "SIMPLE 1");
+		q.setString(0, "Simple 1");
+		q.setFirstResult(0);
+		assertTrue( q.iterate().hasNext() );
+		q = s.createQuery("from Simple s where s.name = :foo and upper(s.name) = :bar or s.count=:count or s.count=:count + 1");
+		q.setParameter("bar", "SIMPLE 1");
+		q.setString("foo", "Simple 1");
+		q.setInteger("count", 69);
+		q.setFirstResult(0);
+		assertTrue( q.iterate().hasNext() );
+		q = s.createQuery("select s.id from Simple s");
+		q.setFirstResult(1);
+		q.setMaxResults(2);
+		iter = q.iterate();
+		int i=0;
+		while ( iter.hasNext() ) {
+			assertTrue( iter.next() instanceof Long );
+			i++;
+		}
+		assertTrue(i==2);
+		q = s.createQuery("select all s, s.other from Simple s where s = :s");
+		q.setParameter("s", simple);
+		assertTrue( q.list().size()==1 );
+
+
+		q = s.createQuery("from Simple s where s.name in (:name_list) and s.count > :count");
+		HashSet set = new HashSet();
+		set.add("Simple 1"); set.add("foo");
+		q.setParameterList( "name_list", set );
+		q.setParameter("count", new Integer(-1) );
+		assertTrue( q.list().size()==1 );
+
+		ScrollableResults sr = s.createQuery("from Simple s").scroll();
+		sr.next();
+		sr.get(0);
+		sr.close();
+
+		s.delete(other);
+		s.delete(simple);
+		s.delete(min);
+		t.commit();
+		s.close();
+
+	}
+
+	public void testBlobClob() throws Exception {
+
+		Session s = openSession();
+		Blobber b = new Blobber();
+		b.setBlob( Hibernate.createBlob( "foo/bar/baz".getBytes() ) );
+		b.setClob( Hibernate.createClob("foo/bar/baz") );
+		s.save(b);
+		//s.refresh(b);
+		//assertTrue( b.getClob() instanceof ClobImpl );
+		s.flush();
+		s.refresh(b);
+		//b.getBlob().setBytes( 2, "abc".getBytes() );
+        log.debug("levinson: just bfore b.getClob()");
+        b.getClob().getSubString(2, 3);
+		//b.getClob().setString(2, "abc");
+		s.flush();
+		s.connection().commit();
+		s.close();
+
+		s = openSession();
+		b = (Blobber) s.load( Blobber.class, new Integer( b.getId() ) );
+		Blobber b2 = new Blobber();
+		s.save(b2);
+		b2.setBlob( b.getBlob() );
+		b.setBlob(null);
+		//assertTrue( b.getClob().getSubString(1, 3).equals("fab") );
+		b.getClob().getSubString(1, 6);
+		//b.getClob().setString(1, "qwerty");
+		s.flush();
+		s.connection().commit();
+		s.close();
+
+		s = openSession();
+		b = (Blobber) s.load( Blobber.class, new Integer( b.getId() ) );
+		b.setClob( Hibernate.createClob("xcvfxvc xcvbx cvbx cvbx cvbxcvbxcvbxcvb") );
+		s.flush();
+		s.connection().commit();
+		s.close();
+
+		s = openSession();
+		b = (Blobber) s.load( Blobber.class, new Integer( b.getId() ) );
+		assertTrue( b.getClob().getSubString(1, 7).equals("xcvfxvc") );
+		//b.getClob().setString(5, "1234567890");
+		s.flush();
+		s.connection().commit();
+		s.close();
+
+
+		/*InputStream is = getClass().getClassLoader().getResourceAsStream("jdbc20.pdf");
+		s = sessionsopenSession();
+		b = (Blobber) s.load( Blobber.class, new Integer( b.getId() ) );
+		System.out.println( is.available() );
+		int size = is.available();
+		b.setBlob( Hibernate.createBlob( is, is.available() ) );
+		s.flush();
+		s.connection().commit();
+		ResultSet rs = s.connection().createStatement().executeQuery("select datalength(blob_) from blobber where id=" + b.getId() );
+		rs.next();
+		assertTrue( size==rs.getInt(1) );
+		rs.close();
+		s.close();
+
+		s = sessionsopenSession();
+		b = (Blobber) s.load( Blobber.class, new Integer( b.getId() ) );
+		File f = new File("C:/foo.pdf");
+		f.createNewFile();
+		FileOutputStream fos = new FileOutputStream(f);
+		Blob blob = b.getBlob();
+		byte[] bytes = blob.getBytes( 1, (int) blob.length() );
+		System.out.println( bytes.length );
+		fos.write(bytes);
+		fos.flush();
+		fos.close();
+		s.close();*/
+
+	}
+
+	public void testSqlFunctionAsAlias() throws Exception {
+		String functionName = locateAppropriateDialectFunctionNameForAliasTest();
+		if (functionName == null) {
+			log.info("Dialect does not list any no-arg functions");
+			return;
+		}
+
+		log.info("Using function named [" + functionName + "] for 'function as alias' test");
+		String query = "select " + functionName + " from Simple as " + functionName + " where " + functionName + ".id = 10";
+
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Simple simple = new Simple();
+		simple.setName("Simple 1");
+		s.save( simple, new Long(10) );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		List result = s.find(query);
+		assertTrue( result.size() == 1 );
+		assertTrue(result.get(0) instanceof Simple);
+		s.delete( result.get(0) );
+		t.commit();
+		s.close();
+	}
+
+	private String locateAppropriateDialectFunctionNameForAliasTest() {
+		for (Iterator itr = getDialect().getFunctions().entrySet().iterator(); itr.hasNext(); ) {
+			final Map.Entry entry = (Map.Entry) itr.next();
+			final SQLFunction function = (SQLFunction) entry.getValue();
+			if ( !function.hasArguments() && !function.hasParenthesesIfNoArguments() ) {
+				return (String) entry.getKey();
+			}
+		}
+		return null;
+	}
+
+	public void testCachedQueryOnInsert() throws Exception {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Simple simple = new Simple();
+		simple.setName("Simple 1");
+		s.save( simple, new Long(10) );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		Query q = s.createQuery("from Simple s");
+		List list = q.setCacheable(true).list();
+		assertTrue( list.size()==1 );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		q = s.createQuery("from Simple s");
+		list = q.setCacheable(true).list();
+		assertTrue( list.size()==1 );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		Simple simple2 = new Simple();
+		simple2.setCount(133);
+		s.save( simple2, new Long(12) );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		q = s.createQuery("from Simple s");
+		list = q.setCacheable(true).list();
+		assertTrue( list.size()==2 );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		q = s.createQuery("from Simple s");
+		list = q.setCacheable(true).list();
+		assertTrue( list.size()==2 );
+		Iterator i = list.iterator();
+		while ( i.hasNext() ) s.delete( i.next() );
+		t.commit();
+		s.close();
+
+	}
+
+    public void testInterSystemsFunctions() throws Exception {
+        Calendar cal = new GregorianCalendar();
+        cal.set(1977,6,3,0,0,0);
+        java.sql.Timestamp testvalue = new java.sql.Timestamp(cal.getTimeInMillis());
+        testvalue.setNanos(0);
+        Calendar cal3 = new GregorianCalendar();
+        cal3.set(1976,2,3,0,0,0);
+        java.sql.Timestamp testvalue3 = new java.sql.Timestamp(cal3.getTimeInMillis());
+        testvalue3.setNanos(0);
+
+        Session s = openSession();
+        Transaction t = s.beginTransaction();
+        try {
+            Statement stmt = s.connection().createStatement();
+            stmt.executeUpdate("DROP FUNCTION spLock FROM TestInterSystemsFunctionsClass");
+            t.commit();
+        }
+        catch (Exception ex) {
+            System.out.println("as we expected stored procedure sp does not exist when we drop it");
+
+        }
+        t = s.beginTransaction();
+        Statement stmt = s.connection().createStatement();
+        String create_function = "CREATE FUNCTION SQLUser.TestInterSystemsFunctionsClass_spLock\n" +
+                "     ( INOUT pHandle %SQLProcContext, \n" +
+                "       ROWID INTEGER \n" +
+                " )\n" +
+                " FOR User.TestInterSystemsFunctionsClass " +
+                "    PROCEDURE\n" +
+                "    RETURNS INTEGER\n" +
+                "    LANGUAGE OBJECTSCRIPT\n" +
+                "    {\n" +
+                "        q 0\n" +
+                "     }";
+        stmt.executeUpdate(create_function);
+        t.commit();
+        t = s.beginTransaction();
+
+        TestInterSystemsFunctionsClass object = new TestInterSystemsFunctionsClass();
+        object.setDateText("1977-07-03");
+        object.setDate1(testvalue);
+        object.setDate3(testvalue3);
+        s.save( object, new Long(10));
+        t.commit();
+        s.close();
+        s = openSession();
+        s.clear();
+        t = s.beginTransaction();
+        TestInterSystemsFunctionsClass test = (TestInterSystemsFunctionsClass) s.get(TestInterSystemsFunctionsClass.class, new Long(10));
+        assertTrue( test.getDate1().equals(testvalue));
+        test = (TestInterSystemsFunctionsClass) s.get(TestInterSystemsFunctionsClass.class, new Long(10), LockMode.UPGRADE);
+        assertTrue( test.getDate1().equals(testvalue));
+        Date value = (Date) s.find("select nvl(o.date,o.dateText) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue( value.equals(testvalue));
+        Object nv = s.find("select nullif(o.dateText,o.dateText) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue( nv == null);
+        String dateText = (String) s.find("select nvl(o.dateText,o.date) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue( dateText.equals("1977-07-03"));
+        value = (Date) s.find("select ifnull(o.date,o.date1) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue( value.equals(testvalue));
+        value = (Date) s.find("select ifnull(o.date3,o.date,o.date1) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue( value.equals(testvalue));
+        Integer pos = (Integer) s.find("select position('07', o.dateText) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue(pos.intValue() == 6);
+        String st = (String) s.find("select convert(o.date1, SQL_TIME) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue( st.equals("00:00:00"));
+        java.sql.Time tm = (java.sql.Time) s.find("select cast(o.date1, time) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue( tm.toString().equals("00:00:00"));
+        Double diff = (Double)s.find("select timestampdiff(SQL_TSI_FRAC_SECOND, o.date3, o.date1) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue(diff.doubleValue() != 0.0);
+        diff = (Double)s.find("select timestampdiff(SQL_TSI_MONTH, o.date3, o.date1) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue(diff.doubleValue() == 16.0);
+        diff = (Double)s.find("select timestampdiff(SQL_TSI_WEEK, o.date3, o.date1) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue(diff.doubleValue() >= 16*4);
+        diff = (Double)s.find("select timestampdiff(SQL_TSI_YEAR, o.date3, o.date1) from TestInterSystemsFunctionsClass as o" ).get(0);
+        assertTrue(diff.doubleValue() == 1.0);
+
+        t.commit();
+        s.close();
+
+
+    }
+
+}

Copied: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.hbm.xml (from rev 10964, branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/cache/TestInterSystemsFunctionsClass.hbm.xml)
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.hbm.xml	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.hbm.xml	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.dialect.functional.cache" >
+
+    <class name="TestInterSystemsFunctionsClass" table="SQLUser.TestInterSystemsFunctionsClass">
+        <id type="long" column="id_">
+            <generator class="assigned"/>
+        </id>
+        <property name="date" column="date_"/>
+        <property name="date1" column="date1_"/>
+        <property name="date3" column="date3_"/>
+        <property name="dateText" column="dateText_"/>
+    </class>
+
+</hibernate-mapping>

Copied: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.java (from rev 10964, branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/cache/TestInterSystemsFunctionsClass.java)
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.java	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/functional/cache/TestInterSystemsFunctionsClass.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,51 @@
+package org.hibernate.test.dialect.functional.cache;
+
+import java.util.Date;
+
+/**
+ * Entity for testing function support of InterSystems' CacheSQL...
+ *
+ * @author Jonathan Levinson
+ */
+public class TestInterSystemsFunctionsClass {
+    private java.util.Date date3;
+    private java.util.Date date1;
+    private java.util.Date date;
+    private String dateText;
+
+	public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+
+    public String getDateText() {
+        return dateText;
+    }
+
+    public void setDateText(String dateText) {
+        this.dateText = dateText;
+    }
+
+
+    public Date getDate1() {
+        return date1;
+    }
+
+    public void setDate1(Date date1) {
+        this.date1 = date1;
+    }
+
+
+    public Date getDate3() {
+        return date3;
+    }
+
+    public void setDate3(Date date3) {
+        this.date3 = date3;
+    }
+
+}

Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/DialectUnitTestsSuite.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/DialectUnitTestsSuite.java	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/DialectUnitTestsSuite.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,20 @@
+package org.hibernate.test.dialect.unit;
+
+import junit.framework.TestSuite;
+
+import org.hibernate.test.dialect.unit.lockhint.SybaseLockHintsTest;
+import org.hibernate.test.dialect.unit.lockhint.SQLServerLockHintsTest;
+
+/**
+ * Suite of all unit tests of the Dialect(s).
+ *
+ * @author Steve Ebersole
+ */
+public class DialectUnitTestsSuite {
+	public static TestSuite suite() {
+		TestSuite suite = new TestSuite( "Dialect unit-tests" );
+		suite.addTest( SybaseLockHintsTest.suite() );
+		suite.addTest( SQLServerLockHintsTest.suite() );
+		return suite;
+	}
+}

Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/AbstractLockHintTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/AbstractLockHintTest.java	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/AbstractLockHintTest.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,64 @@
+package org.hibernate.test.dialect.unit.lockhint;
+
+import java.util.HashMap;
+import java.util.Collections;
+
+import org.hibernate.junit.UnitTestCase;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.StringHelper;
+import org.hibernate.LockMode;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractLockHintTest extends UnitTestCase {
+	public AbstractLockHintTest(String string) {
+		super( string );
+	}
+
+	private Dialect dialect;
+
+	protected abstract String getLockHintUsed();
+	protected abstract Dialect getDialectUnderTest();
+
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.dialect = getDialectUnderTest();
+	}
+
+	protected void tearDown() throws Exception {
+		this.dialect = null;
+		super.tearDown();
+	}
+
+	public void testBasicLocking() {
+		new SyntaxChecker( "select xyz from ABC $HOLDER$", "a" ).verify();
+		new SyntaxChecker( "select xyz from ABC $HOLDER$ join DEF d", "a" ).verify();
+		new SyntaxChecker( "select xyz from ABC $HOLDER$, DEF d", "a" ).verify();
+	}
+
+	protected class SyntaxChecker {
+		private final String aliasToLock;
+		private final String rawSql;
+		private final String expectedProcessedSql;
+
+		public SyntaxChecker(String template) {
+			this( template, "" );
+		}
+
+		public SyntaxChecker(String template, String aliasToLock) {
+			this.aliasToLock = aliasToLock;
+			rawSql = StringHelper.replace( template, "$HOLDER$", aliasToLock );
+			expectedProcessedSql = StringHelper.replace( template, "$HOLDER$", aliasToLock + " " + getLockHintUsed() );
+		}
+
+		public void verify() {
+			HashMap lockModes = new HashMap();
+			lockModes.put( aliasToLock, LockMode.UPGRADE );
+			String actualProcessedSql = dialect.applyLocksToSql( rawSql, lockModes, Collections.EMPTY_MAP );
+			assertEquals( expectedProcessedSql, actualProcessedSql );
+		}
+	}
+}

Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SQLServerLockHintsTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SQLServerLockHintsTest.java	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SQLServerLockHintsTest.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,31 @@
+package org.hibernate.test.dialect.unit.lockhint;
+
+import junit.framework.TestSuite;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.SQLServerDialect;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class SQLServerLockHintsTest extends AbstractLockHintTest {
+	public static final Dialect DIALECT = new SQLServerDialect();
+
+	public SQLServerLockHintsTest(String string) {
+		super( string );
+	}
+
+	protected String getLockHintUsed() {
+		return "with (updlock, rowlock)";
+	}
+
+	protected Dialect getDialectUnderTest() {
+		return DIALECT;
+	}
+
+	public static TestSuite suite() {
+		return new TestSuite( SQLServerLockHintsTest.class );
+	}
+}

Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SybaseLockHintsTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SybaseLockHintsTest.java	                        (rev 0)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/dialect/unit/lockhint/SybaseLockHintsTest.java	2007-01-23 16:31:13 UTC (rev 11081)
@@ -0,0 +1,31 @@
+package org.hibernate.test.dialect.unit.lockhint;
+
+import junit.framework.TestSuite;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.SybaseDialect;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class SybaseLockHintsTest extends AbstractLockHintTest {
+	public static final Dialect DIALECT = new SybaseDialect();
+
+	public SybaseLockHintsTest(String string) {
+		super( string );
+	}
+
+	protected String getLockHintUsed() {
+		return "holdlock";
+	}
+
+	protected Dialect getDialectUnderTest() {
+		return DIALECT;
+	}
+
+	public static TestSuite suite() {
+		return new TestSuite( SybaseLockHintsTest.class );
+	}
+}




More information about the hibernate-commits mailing list