HHH-892 : HQL parser does not resolve alias in ORDER BY clause
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20673 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
dde16433ad
commit
13699d792b
|
@ -50,6 +50,8 @@ tokens
|
||||||
METHOD_NAME; // An IDENT that is a method name.
|
METHOD_NAME; // An IDENT that is a method name.
|
||||||
NAMED_PARAM; // A named parameter (:foo).
|
NAMED_PARAM; // A named parameter (:foo).
|
||||||
BOGUS; // Used for error state detection, etc.
|
BOGUS; // Used for error state detection, etc.
|
||||||
|
RESULT_VARIABLE_REF; // An IDENT that refers to result variable
|
||||||
|
// (i.e, an alias for a select expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Declarations --
|
// -- Declarations --
|
||||||
|
@ -211,7 +213,14 @@ tokens
|
||||||
|
|
||||||
protected void lookupAlias(AST ident) throws SemanticException { }
|
protected void lookupAlias(AST ident) throws SemanticException { }
|
||||||
|
|
||||||
protected void setAlias(AST selectExpr, AST ident) { }
|
protected void setAlias(AST selectExpr, AST ident) { }
|
||||||
|
|
||||||
|
protected boolean isOrderExpressionResultVariableRef(AST ident) throws SemanticException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleResultVariableRef(AST resultVariableRef) throws SemanticException {
|
||||||
|
}
|
||||||
|
|
||||||
protected AST lookupProperty(AST dot,boolean root,boolean inSelect) throws SemanticException {
|
protected AST lookupProperty(AST dot,boolean root,boolean inSelect) throws SemanticException {
|
||||||
return dot;
|
return dot;
|
||||||
|
@ -334,7 +343,20 @@ orderClause
|
||||||
;
|
;
|
||||||
|
|
||||||
orderExprs
|
orderExprs
|
||||||
: expr ( ASCENDING | DESCENDING )? (orderExprs)?
|
: orderExpr ( ASCENDING | DESCENDING )? (orderExprs)?
|
||||||
|
;
|
||||||
|
|
||||||
|
orderExpr
|
||||||
|
: { isOrderExpressionResultVariableRef( _t ) }? resultVariableRef
|
||||||
|
| expr
|
||||||
|
;
|
||||||
|
|
||||||
|
resultVariableRef!
|
||||||
|
: i:identifier {
|
||||||
|
// Create a RESULT_VARIABLE_REF node instead of an IDENT node.
|
||||||
|
#resultVariableRef = #([RESULT_VARIABLE_REF, i.getText()]);
|
||||||
|
handleResultVariableRef(#resultVariableRef);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
groupClause
|
groupClause
|
||||||
|
@ -358,7 +380,7 @@ selectExprList {
|
||||||
|
|
||||||
aliasedSelectExpr!
|
aliasedSelectExpr!
|
||||||
: #(AS se:selectExpr i:identifier) {
|
: #(AS se:selectExpr i:identifier) {
|
||||||
setAlias(#se,#i);
|
setAlias(#se,#i);
|
||||||
#aliasedSelectExpr = #se;
|
#aliasedSelectExpr = #se;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -723,4 +745,4 @@ parameter!
|
||||||
|
|
||||||
numericInteger
|
numericInteger
|
||||||
: NUM_INT
|
: NUM_INT
|
||||||
;
|
;
|
||||||
|
|
|
@ -432,6 +432,7 @@ addrExpr
|
||||||
: #(r:DOT . .) { out(r); }
|
: #(r:DOT . .) { out(r); }
|
||||||
| i:ALIAS_REF { out(i); }
|
| i:ALIAS_REF { out(i); }
|
||||||
| j:INDEX_OP { out(j); }
|
| j:INDEX_OP { out(j); }
|
||||||
|
| v:RESULT_VARIABLE_REF { out(v); }
|
||||||
;
|
;
|
||||||
|
|
||||||
sqlToken
|
sqlToken
|
||||||
|
|
|
@ -1723,6 +1723,20 @@ public abstract class Dialect {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this dialect require that references to result variables
|
||||||
|
* (i.e, select expresssion aliases) in an ORDER BY clause be
|
||||||
|
* replaced by column positions (1-origin) as defined
|
||||||
|
* by the select clause?
|
||||||
|
|
||||||
|
* @return true if result variable references in the ORDER BY
|
||||||
|
* clause should be replaced by column positions;
|
||||||
|
* false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean replaceResultVariableInOrderByClauseWithPosition() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this dialect require that parameters appearing in the <tt>SELECT</tt> clause be wrapped in <tt>cast()</tt>
|
* Does this dialect require that parameters appearing in the <tt>SELECT</tt> clause be wrapped in <tt>cast()</tt>
|
||||||
* calls to tell the db parser the expected type.
|
* calls to tell the db parser the expected type.
|
||||||
|
|
|
@ -66,6 +66,7 @@ import org.hibernate.hql.ast.tree.ParameterNode;
|
||||||
import org.hibernate.hql.ast.tree.QueryNode;
|
import org.hibernate.hql.ast.tree.QueryNode;
|
||||||
import org.hibernate.hql.ast.tree.ResolvableNode;
|
import org.hibernate.hql.ast.tree.ResolvableNode;
|
||||||
import org.hibernate.hql.ast.tree.RestrictableStatement;
|
import org.hibernate.hql.ast.tree.RestrictableStatement;
|
||||||
|
import org.hibernate.hql.ast.tree.ResultVariableRefNode;
|
||||||
import org.hibernate.hql.ast.tree.SelectClause;
|
import org.hibernate.hql.ast.tree.SelectClause;
|
||||||
import org.hibernate.hql.ast.tree.SelectExpression;
|
import org.hibernate.hql.ast.tree.SelectExpression;
|
||||||
import org.hibernate.hql.ast.tree.UpdateStatement;
|
import org.hibernate.hql.ast.tree.UpdateStatement;
|
||||||
|
@ -132,6 +133,12 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
||||||
private FromClause currentFromClause = null;
|
private FromClause currentFromClause = null;
|
||||||
private SelectClause selectClause;
|
private SelectClause selectClause;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps each top-level result variable to its SelectExpression;
|
||||||
|
* (excludes result variables defined in subqueries)
|
||||||
|
**/
|
||||||
|
private Map<String, SelectExpression> selectExpressionsByResultVariable = new HashMap();
|
||||||
|
|
||||||
private Set querySpaces = new HashSet();
|
private Set querySpaces = new HashSet();
|
||||||
|
|
||||||
private int parameterCount;
|
private int parameterCount;
|
||||||
|
@ -991,8 +998,35 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
||||||
|
|
||||||
protected void setAlias(AST selectExpr, AST ident) {
|
protected void setAlias(AST selectExpr, AST ident) {
|
||||||
((SelectExpression) selectExpr).setAlias(ident.getText());
|
((SelectExpression) selectExpr).setAlias(ident.getText());
|
||||||
|
// only put the alias (i.e., result variable) in selectExpressionsByResultVariable
|
||||||
|
// if is not defined in a subquery.
|
||||||
|
if ( ! isSubQuery() ) {
|
||||||
|
selectExpressionsByResultVariable.put( ident.getText(), ( SelectExpression ) selectExpr );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isOrderExpressionResultVariableRef(AST orderExpressionNode) throws SemanticException {
|
||||||
|
// ORDER BY is not supported in a subquery
|
||||||
|
// TODO: should an exception be thrown if an ORDER BY is in a subquery?
|
||||||
|
if ( ! isSubQuery() &&
|
||||||
|
orderExpressionNode.getType() == IDENT &&
|
||||||
|
selectExpressionsByResultVariable.containsKey( orderExpressionNode.getText() ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleResultVariableRef(AST resultVariableRef) throws SemanticException {
|
||||||
|
if ( isSubQuery() ) {
|
||||||
|
throw new SemanticException(
|
||||||
|
"References to result variables in subqueries are not supported."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
( ( ResultVariableRefNode ) resultVariableRef ).setSelectExpression(
|
||||||
|
selectExpressionsByResultVariable.get( resultVariableRef.getText() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the locations of all occurrences of the named parameter.
|
* Returns the locations of all occurrences of the named parameter.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.hibernate.hql.ast.tree.MethodNode;
|
||||||
import org.hibernate.hql.ast.tree.OrderByClause;
|
import org.hibernate.hql.ast.tree.OrderByClause;
|
||||||
import org.hibernate.hql.ast.tree.ParameterNode;
|
import org.hibernate.hql.ast.tree.ParameterNode;
|
||||||
import org.hibernate.hql.ast.tree.QueryNode;
|
import org.hibernate.hql.ast.tree.QueryNode;
|
||||||
|
import org.hibernate.hql.ast.tree.ResultVariableRefNode;
|
||||||
import org.hibernate.hql.ast.tree.SelectClause;
|
import org.hibernate.hql.ast.tree.SelectClause;
|
||||||
import org.hibernate.hql.ast.tree.SelectExpressionImpl;
|
import org.hibernate.hql.ast.tree.SelectExpressionImpl;
|
||||||
import org.hibernate.hql.ast.tree.SqlFragment;
|
import org.hibernate.hql.ast.tree.SqlFragment;
|
||||||
|
@ -124,6 +125,8 @@ public class SqlASTFactory extends ASTFactory implements HqlSqlTokenTypes {
|
||||||
case ALIAS_REF:
|
case ALIAS_REF:
|
||||||
case IDENT:
|
case IDENT:
|
||||||
return IdentNode.class;
|
return IdentNode.class;
|
||||||
|
case RESULT_VARIABLE_REF:
|
||||||
|
return ResultVariableRefNode.class;
|
||||||
case SQL_TOKEN:
|
case SQL_TOKEN:
|
||||||
return SqlFragment.class;
|
return SqlFragment.class;
|
||||||
case METHOD_CALL:
|
case METHOD_CALL:
|
||||||
|
|
|
@ -36,6 +36,7 @@ import antlr.SemanticException;
|
||||||
public abstract class AbstractSelectExpression extends HqlSqlWalkerNode implements SelectExpression {
|
public abstract class AbstractSelectExpression extends HqlSqlWalkerNode implements SelectExpression {
|
||||||
|
|
||||||
private String alias;
|
private String alias;
|
||||||
|
private int scalarColumnIndex = -1;
|
||||||
|
|
||||||
public final void setAlias(String alias) {
|
public final void setAlias(String alias) {
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
|
@ -63,4 +64,13 @@ public abstract class AbstractSelectExpression extends HqlSqlWalkerNode implemen
|
||||||
Type type = getDataType();
|
Type type = getDataType();
|
||||||
return type != null && !type.isAssociationType(); // Moved here from SelectClause [jsd]
|
return type != null && !type.isAssociationType(); // Moved here from SelectClause [jsd]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setScalarColumn(int i) throws SemanticException {
|
||||||
|
this.scalarColumnIndex = i;
|
||||||
|
setScalarColumnText( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScalarColumnIndex() {
|
||||||
|
return scalarColumnIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class ConstructorNode extends SelectExpressionList implements AggregatedS
|
||||||
private Type[] constructorArgumentTypes;
|
private Type[] constructorArgumentTypes;
|
||||||
private boolean isMap;
|
private boolean isMap;
|
||||||
private boolean isList;
|
private boolean isList;
|
||||||
|
private int scalarColumnIndex = -1;
|
||||||
|
|
||||||
public ResultTransformer getResultTransformer() {
|
public ResultTransformer getResultTransformer() {
|
||||||
if ( constructor != null ) {
|
if ( constructor != null ) {
|
||||||
|
@ -92,6 +93,19 @@ public class ConstructorNode extends SelectExpressionList implements AggregatedS
|
||||||
return aliases;
|
return aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setScalarColumn(int i) throws SemanticException {
|
||||||
|
SelectExpression[] selectExpressions = collectSelectExpressions();
|
||||||
|
// Invoke setScalarColumnText on each constructor argument.
|
||||||
|
for ( int j = 0; j < selectExpressions.length; j++ ) {
|
||||||
|
SelectExpression selectExpression = selectExpressions[j];
|
||||||
|
selectExpression.setScalarColumn( j );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScalarColumnIndex() {
|
||||||
|
return scalarColumnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public void setScalarColumnText(int i) throws SemanticException {
|
public void setScalarColumnText(int i) throws SemanticException {
|
||||||
SelectExpression[] selectExpressions = collectSelectExpressions();
|
SelectExpression[] selectExpressions = collectSelectExpressions();
|
||||||
// Invoke setScalarColumnText on each constructor argument.
|
// Invoke setScalarColumnText on each constructor argument.
|
||||||
|
|
|
@ -60,6 +60,8 @@ public class MapEntryNode extends AbstractMapComponentNode implements Aggregated
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int scalarColumnIndex = -1;
|
||||||
|
|
||||||
protected String expressionDescription() {
|
protected String expressionDescription() {
|
||||||
return "entry(*)";
|
return "entry(*)";
|
||||||
}
|
}
|
||||||
|
@ -190,6 +192,14 @@ public class MapEntryNode extends AbstractMapComponentNode implements Aggregated
|
||||||
super.setText( s );
|
super.setText( s );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setScalarColumn(int i) throws SemanticException {
|
||||||
|
this.scalarColumnIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScalarColumnIndex() {
|
||||||
|
return scalarColumnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public void setScalarColumnText(int i) throws SemanticException {
|
public void setScalarColumnText(int i) throws SemanticException {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ public class QueryNode extends AbstractRestrictableStatement implements SelectEx
|
||||||
private static final Logger log = LoggerFactory.getLogger( QueryNode.class );
|
private static final Logger log = LoggerFactory.getLogger( QueryNode.class );
|
||||||
|
|
||||||
private OrderByClause orderByClause;
|
private OrderByClause orderByClause;
|
||||||
|
private int scalarColumnIndex = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Statement#getStatementType()
|
* @see Statement#getStatementType()
|
||||||
|
@ -145,6 +146,15 @@ public class QueryNode extends AbstractRestrictableStatement implements SelectEx
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setScalarColumn(int i) throws SemanticException {
|
||||||
|
scalarColumnIndex = i;
|
||||||
|
setScalarColumnText( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScalarColumnIndex() {
|
||||||
|
return scalarColumnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public void setScalarColumnText(int i) throws SemanticException {
|
public void setScalarColumnText(int i) throws SemanticException {
|
||||||
ColumnHelper.generateSingleScalarColumn( this, i );
|
ColumnHelper.generateSingleScalarColumn( this, i );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Middleware LLC.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.hql.ast.tree;
|
||||||
|
|
||||||
|
import antlr.SemanticException;
|
||||||
|
|
||||||
|
import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.util.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a reference to a result_variable as defined in the JPA 2 spec.
|
||||||
|
* For example:
|
||||||
|
* <code>
|
||||||
|
* select v as value from tab1 order by value
|
||||||
|
* </code>
|
||||||
|
* <p/>
|
||||||
|
* "value" used in the order by clause is a reference to the
|
||||||
|
* result_variable, "value", defined in the select clause.
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class ResultVariableRefNode extends HqlSqlWalkerNode {
|
||||||
|
private SelectExpression selectExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the select expression that defines the result variable.
|
||||||
|
*
|
||||||
|
* @param selectExpression the select expression;
|
||||||
|
* selectExpression.getAlias() must be non-null
|
||||||
|
* @throws SemanticException if selectExpression or
|
||||||
|
* selectExpression.getAlias() is null.
|
||||||
|
*/
|
||||||
|
public void setSelectExpression(SelectExpression selectExpression) throws SemanticException {
|
||||||
|
if ( selectExpression == null || selectExpression.getAlias() == null ) {
|
||||||
|
throw new SemanticException( "A ResultVariableRefNode must refer to a non-null alias." );
|
||||||
|
}
|
||||||
|
this.selectExpression = selectExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String getRenderText(SessionFactoryImplementor sessionFactory) {
|
||||||
|
int scalarColumnIndex = selectExpression.getScalarColumnIndex();
|
||||||
|
if ( scalarColumnIndex < 0 ) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"selectExpression.getScalarColumnIndex() must be >= 0; actual = " + scalarColumnIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return sessionFactory.getDialect().replaceResultVariableInOrderByClauseWithPosition() ?
|
||||||
|
getColumnPositionsString( scalarColumnIndex ) :
|
||||||
|
getColumnNamesString( scalarColumnIndex );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getColumnPositionsString(int scalarColumnIndex ) {
|
||||||
|
int startPosition = getWalker().getSelectClause().getColumnNamesStartPosition( scalarColumnIndex );
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
int nColumns = getWalker().getSelectClause().getColumnNames()[ scalarColumnIndex ].length;
|
||||||
|
for ( int i = startPosition; i < startPosition + nColumns; i++ ) {
|
||||||
|
if ( i > startPosition ) {
|
||||||
|
buf.append( ", " );
|
||||||
|
}
|
||||||
|
buf.append( i );
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getColumnNamesString(int scalarColumnIndex) {
|
||||||
|
return StringHelper.join( ", ", getWalker().getSelectClause().getColumnNames()[ scalarColumnIndex ] );
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
package org.hibernate.hql.ast.tree;
|
package org.hibernate.hql.ast.tree;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ public class SelectClause extends SelectExpressionList {
|
||||||
private String[][] columnNames;
|
private String[][] columnNames;
|
||||||
private List collectionFromElements;
|
private List collectionFromElements;
|
||||||
private String[] aliases;
|
private String[] aliases;
|
||||||
|
private int[] columnNamesStartPositions;
|
||||||
|
|
||||||
// Currently we can only have one...
|
// Currently we can only have one...
|
||||||
private AggregatedSelectExpression aggregatedSelectExpression;
|
private AggregatedSelectExpression aggregatedSelectExpression;
|
||||||
|
@ -253,6 +255,16 @@ public class SelectClause extends SelectExpressionList {
|
||||||
|
|
||||||
// todo: we should really just collect these from the various SelectExpressions, rather than regenerating here
|
// todo: we should really just collect these from the various SelectExpressions, rather than regenerating here
|
||||||
columnNames = getSessionFactoryHelper().generateColumnNames( queryReturnTypes );
|
columnNames = getSessionFactoryHelper().generateColumnNames( queryReturnTypes );
|
||||||
|
columnNamesStartPositions = new int[ columnNames.length ];
|
||||||
|
int startPosition = 1;
|
||||||
|
for ( int i = 0 ; i < columnNames.length ; i ++ ) {
|
||||||
|
columnNamesStartPositions[ i ] = startPosition;
|
||||||
|
startPosition += columnNames[ i ].length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnNamesStartPosition(int i) {
|
||||||
|
return columnNamesStartPositions[ i ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -356,7 +368,7 @@ public class SelectClause extends SelectExpressionList {
|
||||||
if ( !currentFromClause.isSubQuery() ) {
|
if ( !currentFromClause.isSubQuery() ) {
|
||||||
for ( int i = 0; i < se.length; i++ ) {
|
for ( int i = 0; i < se.length; i++ ) {
|
||||||
SelectExpression expr = se[i];
|
SelectExpression expr = se[i];
|
||||||
expr.setScalarColumnText( i ); // Create SQL_TOKEN nodes for the columns.
|
expr.setScalarColumn( i ); // Create SQL_TOKEN nodes for the columns.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,21 @@ public interface SelectExpression {
|
||||||
*/
|
*/
|
||||||
void setScalarColumnText(int i) throws SemanticException;
|
void setScalarColumnText(int i) throws SemanticException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the index and text for select expression in the projection list.
|
||||||
|
*
|
||||||
|
* @param i The index of the select expression in the projection list.
|
||||||
|
* @throws SemanticException
|
||||||
|
*/
|
||||||
|
void setScalarColumn(int i) throws SemanticException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets index of the select expression in the projection list.
|
||||||
|
*
|
||||||
|
* @returns The index of the select expression in the projection list.
|
||||||
|
*/
|
||||||
|
int getScalarColumnIndex();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the FROM element that this expression refers to.
|
* Returns the FROM element that this expression refers to.
|
||||||
*
|
*
|
||||||
|
|
|
@ -100,6 +100,10 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
private Zoo zoo4;
|
private Zoo zoo4;
|
||||||
Set<Zoo> zoosWithSameName;
|
Set<Zoo> zoosWithSameName;
|
||||||
Set<Zoo> zoosWithSameAddress;
|
Set<Zoo> zoosWithSameAddress;
|
||||||
|
Mammal zoo1Mammal1;
|
||||||
|
Mammal zoo1Mammal2;
|
||||||
|
Human zoo2Director1;
|
||||||
|
Human zoo2Director2;
|
||||||
|
|
||||||
public ASTParserLoadingOrderByTest(String name) {
|
public ASTParserLoadingOrderByTest(String name) {
|
||||||
super( name );
|
super( name );
|
||||||
|
@ -138,6 +142,14 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
address1.setStateProvince( stateProvince );
|
address1.setStateProvince( stateProvince );
|
||||||
address1.setCountry( "USA" );
|
address1.setCountry( "USA" );
|
||||||
zoo1.setAddress( address1 );
|
zoo1.setAddress( address1 );
|
||||||
|
zoo1Mammal1 = new Mammal();
|
||||||
|
zoo1Mammal1.setDescription( "zoo1Mammal1" );
|
||||||
|
zoo1Mammal1.setZoo( zoo1 );
|
||||||
|
zoo1.getMammals().put( "type1", zoo1Mammal1);
|
||||||
|
zoo1Mammal2 = new Mammal();
|
||||||
|
zoo1Mammal2.setDescription( "zoo1Mammal2" );
|
||||||
|
zoo1Mammal2.setZoo( zoo1 );
|
||||||
|
zoo1.getMammals().put( "type1", zoo1Mammal2);
|
||||||
|
|
||||||
zoo2 = new Zoo();
|
zoo2 = new Zoo();
|
||||||
zoo2.setName( "A Zoo" );
|
zoo2.setName( "A Zoo" );
|
||||||
|
@ -147,7 +159,12 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
address2.setStateProvince( stateProvince );
|
address2.setStateProvince( stateProvince );
|
||||||
address2.setCountry( "USA" );
|
address2.setCountry( "USA" );
|
||||||
zoo2.setAddress( address2 );
|
zoo2.setAddress( address2 );
|
||||||
|
zoo2Director1 = new Human();
|
||||||
|
zoo2Director1.setName( new Name( "Duh", 'A', "Man" ) );
|
||||||
|
zoo2Director2 = new Human();
|
||||||
|
zoo2Director2.setName( new Name( "Fat", 'A', "Cat" ) );
|
||||||
|
zoo2.getDirectors().put( "Head Honcho", zoo2Director1 );
|
||||||
|
zoo2.getDirectors().put( "Asst. Head Honcho", zoo2Director2 );
|
||||||
|
|
||||||
zoo3 = new Zoo();
|
zoo3 = new Zoo();
|
||||||
zoo3.setName( "Zoo" );
|
zoo3.setName( "Zoo" );
|
||||||
|
@ -170,7 +187,11 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
Session s = openSession();
|
Session s = openSession();
|
||||||
Transaction t = s.beginTransaction();
|
Transaction t = s.beginTransaction();
|
||||||
s.save( stateProvince );
|
s.save( stateProvince );
|
||||||
|
s.save( zoo1Mammal1 );
|
||||||
|
s.save( zoo1Mammal2 );
|
||||||
s.save( zoo1 );
|
s.save( zoo1 );
|
||||||
|
s.save( zoo2Director1 );
|
||||||
|
s.save( zoo2Director2 );
|
||||||
s.save( zoo2 );
|
s.save( zoo2 );
|
||||||
s.save( zoo3 );
|
s.save( zoo3 );
|
||||||
s.save( zoo4 );
|
s.save( zoo4 );
|
||||||
|
@ -204,6 +225,25 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
s.delete( zoo4 );
|
s.delete( zoo4 );
|
||||||
zoo4 = null;
|
zoo4 = null;
|
||||||
}
|
}
|
||||||
|
if ( zoo1Mammal1 != null ) {
|
||||||
|
s.delete( zoo1Mammal1 );
|
||||||
|
zoo1Mammal1 = null;
|
||||||
|
}
|
||||||
|
if ( zoo1Mammal2 != null ) {
|
||||||
|
s.delete( zoo1Mammal2 );
|
||||||
|
zoo1Mammal2 = null;
|
||||||
|
}
|
||||||
|
if ( zoo2Director1 != null ) {
|
||||||
|
s.delete( zoo2Director1 );
|
||||||
|
zoo2Director1 = null;
|
||||||
|
}
|
||||||
|
if ( zoo2Director2 != null ) {
|
||||||
|
s.delete( zoo2Director2 );
|
||||||
|
zoo2Director2 = null;
|
||||||
|
}
|
||||||
|
if ( stateProvince != null ) {
|
||||||
|
s.delete( stateProvince );
|
||||||
|
}
|
||||||
t.commit();
|
t.commit();
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
@ -346,7 +386,7 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
cleanupData();
|
cleanupData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOrderBySelectAliasRefFailureExpected() {
|
public void testOrderBySelectAliasRef() {
|
||||||
createData();
|
createData();
|
||||||
|
|
||||||
Session s = openSession();
|
Session s = openSession();
|
||||||
|
@ -492,22 +532,6 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
t.commit();
|
t.commit();
|
||||||
s.close();
|
s.close();
|
||||||
|
|
||||||
s = openSession();
|
|
||||||
t = s.beginTransaction();
|
|
||||||
try {
|
|
||||||
s.createQuery(
|
|
||||||
"select z2.name as zname, z2.address as zooAddress from Zoo z2 where z2.name in ( select name as zname from Zoo order by zname ) order by zooAddress"
|
|
||||||
).list();
|
|
||||||
fail( "Exception should have been thrown because subquery has ORDER BY" );
|
|
||||||
}
|
|
||||||
catch ( QuerySyntaxException ex ) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
t.rollback();
|
|
||||||
s.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanupData();
|
cleanupData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,6 +560,143 @@ public class ASTParserLoadingOrderByTest extends FunctionalTestCase {
|
||||||
cleanupData();
|
cleanupData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testOrderByEntityWithFetchJoinedCollection() {
|
||||||
|
createData();
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
|
||||||
|
// ordered by address desc, name desc:
|
||||||
|
// zoo3 Zoo 1312 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo4 Duh Zoo 1312 Mockingbird Lane, Nowhere, IL USA
|
||||||
|
// zoo2 A Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo1 Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// using DESC
|
||||||
|
List list = s.createQuery( "from Zoo z join fetch z.mammals" ).list();
|
||||||
|
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
cleanupData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOrderBySelectNewArgAliasRef() {
|
||||||
|
createData();
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
|
||||||
|
// ordered by name, address:
|
||||||
|
// zoo2 A Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo4 Duh Zoo 1312 Mockingbird Lane, Nowhere, IL USA
|
||||||
|
// zoo3 Zoo 1312 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo1 Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
List list =
|
||||||
|
s.createQuery(
|
||||||
|
"select new Zoo( z.name as zname, z.address as zaddress) from Zoo z order by zname, zaddress"
|
||||||
|
).list();
|
||||||
|
assertEquals( 4, list.size() );
|
||||||
|
assertEquals( zoo2, list.get( 0 ) );
|
||||||
|
assertEquals( zoo4, list.get( 1 ) );
|
||||||
|
assertEquals( zoo3, list.get( 2 ) );
|
||||||
|
assertEquals( zoo1, list.get( 3 ) );
|
||||||
|
|
||||||
|
// ordered by address, name:
|
||||||
|
// zoo3 Zoo 1312 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo4 Duh Zoo 1312 Mockingbird Lane, Nowhere, IL USA
|
||||||
|
// zoo2 A Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo1 Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
list =
|
||||||
|
s.createQuery(
|
||||||
|
"select new Zoo( z.name as zname, z.address as zaddress) from Zoo z order by zaddress, zname"
|
||||||
|
).list();
|
||||||
|
assertEquals( 4, list.size() );
|
||||||
|
assertEquals( zoo3, list.get( 0 ) );
|
||||||
|
assertEquals( zoo4, list.get( 1 ) );
|
||||||
|
assertEquals( zoo2, list.get( 2 ) );
|
||||||
|
assertEquals( zoo1, list.get( 3 ) );
|
||||||
|
|
||||||
|
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
cleanupData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOrderBySelectNewMapArgAliasRef() {
|
||||||
|
createData();
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
|
||||||
|
// ordered by name, address:
|
||||||
|
// zoo2 A Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo4 Duh Zoo 1312 Mockingbird Lane, Nowhere, IL USA
|
||||||
|
// zoo3 Zoo 1312 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo1 Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
List list =
|
||||||
|
s.createQuery(
|
||||||
|
"select new map( z.name as zname, z.address as zaddress ) from Zoo z left join z.mammals m order by zname, zaddress"
|
||||||
|
).list();
|
||||||
|
assertEquals( 4, list.size() );
|
||||||
|
assertEquals( zoo2.getName(), ( ( Map ) list.get( 0 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo2.getAddress(), ( ( Map ) list.get( 0 ) ).get( "zaddress" ) );
|
||||||
|
assertEquals( zoo4.getName(), ( ( Map ) list.get( 1 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo4.getAddress(), ( ( Map ) list.get( 1 ) ).get( "zaddress" ) );
|
||||||
|
assertEquals( zoo3.getName(), ( ( Map ) list.get( 2 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo3.getAddress(), ( ( Map ) list.get( 2 ) ).get( "zaddress" ) );
|
||||||
|
assertEquals( zoo1.getName(), ( ( Map ) list.get( 3 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo1.getAddress(), ( ( Map ) list.get( 3 ) ).get( "zaddress" ) );
|
||||||
|
|
||||||
|
// ordered by address, name:
|
||||||
|
// zoo3 Zoo 1312 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo4 Duh Zoo 1312 Mockingbird Lane, Nowhere, IL USA
|
||||||
|
// zoo2 A Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo1 Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
list =
|
||||||
|
s.createQuery(
|
||||||
|
"select new map( z.name as zname, z.address as zaddress ) from Zoo z left join z.mammals m order by zaddress, zname"
|
||||||
|
).list();
|
||||||
|
assertEquals( 4, list.size() );
|
||||||
|
assertEquals( zoo3.getName(), ( ( Map ) list.get( 0 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo3.getAddress(), ( ( Map ) list.get( 0 ) ).get( "zaddress" ) );
|
||||||
|
assertEquals( zoo4.getName(), ( ( Map ) list.get( 1 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo4.getAddress(), ( ( Map ) list.get( 1 ) ).get( "zaddress" ) );
|
||||||
|
assertEquals( zoo2.getName(), ( ( Map ) list.get( 2 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo2.getAddress(), ( ( Map ) list.get( 2 ) ).get( "zaddress" ) );
|
||||||
|
assertEquals( zoo1.getName(), ( ( Map ) list.get( 3 ) ).get( "zname" ) );
|
||||||
|
assertEquals( zoo1.getAddress(), ( ( Map ) list.get( 3 ) ).get( "zaddress" ) );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
cleanupData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOrderByAggregatedArgAliasRef() {
|
||||||
|
createData();
|
||||||
|
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
|
||||||
|
// ordered by name, address:
|
||||||
|
// zoo2 A Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo4 Duh Zoo 1312 Mockingbird Lane, Nowhere, IL USA
|
||||||
|
// zoo3 Zoo 1312 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
// zoo1 Zoo 1313 Mockingbird Lane, Anywhere, IL USA
|
||||||
|
List list =
|
||||||
|
s.createQuery(
|
||||||
|
"select z.name as zname, count(*) as cnt from Zoo z group by z.name order by cnt desc, zname"
|
||||||
|
).list();
|
||||||
|
assertEquals( 3, list.size() );
|
||||||
|
assertEquals( zoo3.getName(), ( ( Object[] ) list.get( 0 ) )[ 0 ] );
|
||||||
|
assertEquals( Long.valueOf( 2 ), ( ( Object[] ) list.get( 0 ) )[ 1 ] );
|
||||||
|
assertEquals( zoo2.getName(), ( ( Object[] ) list.get( 1 ) )[ 0 ] );
|
||||||
|
assertEquals( Long.valueOf( 1 ), ( ( Object[] ) list.get( 1 ) )[ 1 ] );
|
||||||
|
assertEquals( zoo4.getName(), ( ( Object[] ) list.get( 2 ) )[ 0 ] );
|
||||||
|
assertEquals( Long.valueOf( 1 ), ( ( Object[] ) list.get( 2 ) )[ 1 ] );
|
||||||
|
cleanupData();
|
||||||
|
}
|
||||||
|
|
||||||
private void checkTestOrderByResults(List results,
|
private void checkTestOrderByResults(List results,
|
||||||
Zoo zoo1,
|
Zoo zoo1,
|
||||||
Zoo zoo2,
|
Zoo zoo2,
|
||||||
|
|
|
@ -2068,6 +2068,96 @@ public class ASTParserLoadingTest extends FunctionalTestCase {
|
||||||
destroyTestBaseData();
|
destroyTestBaseData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testJoinFetchedCollectionOfJoinedSubclass() throws Exception {
|
||||||
|
Mammal mammal = new Mammal();
|
||||||
|
mammal.setDescription( "A Zebra" );
|
||||||
|
Zoo zoo = new Zoo();
|
||||||
|
zoo.setName( "A Zoo" );
|
||||||
|
zoo.getMammals().put( "zebra", mammal );
|
||||||
|
mammal.setZoo( zoo );
|
||||||
|
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction txn = session.beginTransaction();
|
||||||
|
session.save( mammal );
|
||||||
|
session.save( zoo );
|
||||||
|
txn.commit();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
txn = session.beginTransaction();
|
||||||
|
List results = session.createQuery( "from Zoo z join fetch z.mammals" ).list();
|
||||||
|
assertEquals( "Incorrect result size", 1, results.size() );
|
||||||
|
assertTrue( "Incorrect result return type", results.get( 0 ) instanceof Zoo );
|
||||||
|
Zoo zooRead = ( Zoo ) results.get( 0 );
|
||||||
|
assertEquals( zoo, zooRead );
|
||||||
|
assertTrue( Hibernate.isInitialized( zooRead.getMammals() ) );
|
||||||
|
Mammal mammalRead = ( Mammal ) ( ( Map ) zooRead.getMammals() ).get( "zebra" );
|
||||||
|
assertEquals( mammal, mammalRead );
|
||||||
|
session.delete( mammalRead );
|
||||||
|
session.delete( zooRead );
|
||||||
|
txn.commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testJoinedCollectionOfJoinedSubclass() throws Exception {
|
||||||
|
Mammal mammal = new Mammal();
|
||||||
|
mammal.setDescription( "A Zebra" );
|
||||||
|
Zoo zoo = new Zoo();
|
||||||
|
zoo.setName( "A Zoo" );
|
||||||
|
zoo.getMammals().put( "zebra", mammal );
|
||||||
|
mammal.setZoo( zoo );
|
||||||
|
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction txn = session.beginTransaction();
|
||||||
|
session.save( mammal );
|
||||||
|
session.save( zoo );
|
||||||
|
txn.commit();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
txn = session.beginTransaction();
|
||||||
|
List results = session.createQuery( "from Zoo z join z.mammals m" ).list();
|
||||||
|
assertEquals( "Incorrect result size", 1, results.size() );
|
||||||
|
assertTrue( "Incorrect result return type", results.get( 0 ) instanceof Object[] );
|
||||||
|
Object[] resultObjects = ( Object[] ) results.get( 0 );
|
||||||
|
Zoo zooRead = ( Zoo ) resultObjects[ 0 ];
|
||||||
|
Mammal mammalRead = ( Mammal ) resultObjects[ 1 ];
|
||||||
|
assertEquals( zoo, zooRead );
|
||||||
|
assertEquals( mammal, mammalRead );
|
||||||
|
session.delete( mammalRead );
|
||||||
|
session.delete( zooRead );
|
||||||
|
txn.commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testJoinedCollectionOfJoinedSubclassProjection() throws Exception {
|
||||||
|
Mammal mammal = new Mammal();
|
||||||
|
mammal.setDescription( "A Zebra" );
|
||||||
|
Zoo zoo = new Zoo();
|
||||||
|
zoo.setName( "A Zoo" );
|
||||||
|
zoo.getMammals().put( "zebra", mammal );
|
||||||
|
mammal.setZoo( zoo );
|
||||||
|
|
||||||
|
Session session = openSession();
|
||||||
|
Transaction txn = session.beginTransaction();
|
||||||
|
session.save( mammal );
|
||||||
|
session.save( zoo );
|
||||||
|
txn.commit();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
txn = session.beginTransaction();
|
||||||
|
List results = session.createQuery( "select z, m from Zoo z join z.mammals m" ).list();
|
||||||
|
assertEquals( "Incorrect result size", 1, results.size() );
|
||||||
|
assertTrue( "Incorrect result return type", results.get( 0 ) instanceof Object[] );
|
||||||
|
Object[] resultObjects = ( Object[] ) results.get( 0 );
|
||||||
|
Zoo zooRead = ( Zoo ) resultObjects[ 0 ];
|
||||||
|
Mammal mammalRead = ( Mammal ) resultObjects[ 1 ];
|
||||||
|
assertEquals( zoo, zooRead );
|
||||||
|
assertEquals( mammal, mammalRead );
|
||||||
|
session.delete( mammalRead );
|
||||||
|
session.delete( zooRead );
|
||||||
|
txn.commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
public void testProjectionQueries() throws Exception {
|
public void testProjectionQueries() throws Exception {
|
||||||
|
|
||||||
createTestBaseData();
|
createTestBaseData();
|
||||||
|
|
|
@ -112,6 +112,11 @@
|
||||||
<discriminator column="zooType" type="character"/>
|
<discriminator column="zooType" type="character"/>
|
||||||
<property name="name" type="string"/>
|
<property name="name" type="string"/>
|
||||||
<property name="classification" type="org.hibernate.test.hql.ClassificationType"/>
|
<property name="classification" type="org.hibernate.test.hql.ClassificationType"/>
|
||||||
|
<map name="directors">
|
||||||
|
<key column="directorZoo_id"/>
|
||||||
|
<index type="string" column="title"/>
|
||||||
|
<many-to-many class="Human"/>
|
||||||
|
</map>
|
||||||
<map name="mammals">
|
<map name="mammals">
|
||||||
<key column="mammalZoo_id"/>
|
<key column="mammalZoo_id"/>
|
||||||
<index type="string" column="name"/>
|
<index type="string" column="name"/>
|
||||||
|
|
|
@ -1199,7 +1199,7 @@ public class HQLTest extends QueryTranslatorTestCase {
|
||||||
IndexNode n = new IndexNode();
|
IndexNode n = new IndexNode();
|
||||||
Exception ex = null;
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
n.setScalarColumnText( 0 );
|
n.setScalarColumn( 0 );
|
||||||
}
|
}
|
||||||
catch ( UnsupportedOperationException e ) {
|
catch ( UnsupportedOperationException e ) {
|
||||||
ex = e;
|
ex = e;
|
||||||
|
|
|
@ -26,5 +26,32 @@ public class Mammal extends Animal {
|
||||||
public void setBirthdate(Date birthdate) {
|
public void setBirthdate(Date birthdate) {
|
||||||
this.birthdate = birthdate;
|
this.birthdate = birthdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( !( o instanceof Mammal ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mammal mammal = ( Mammal ) o;
|
||||||
|
|
||||||
|
if ( pregnant != mammal.pregnant ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( birthdate != null ? !birthdate.equals( mammal.birthdate ) : mammal.birthdate != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = ( pregnant ? 1 : 0 );
|
||||||
|
result = 31 * result + ( birthdate != null ? birthdate.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//$Id: Zoo.java 10653 2006-10-26 13:38:50Z steve.ebersole@jboss.com $
|
//$Id: Zoo.java 10653 2006-10-26 13:38:50Z steve.ebersole@jboss.com $
|
||||||
package org.hibernate.test.hql;
|
package org.hibernate.test.hql;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,10 +11,18 @@ public class Zoo {
|
||||||
private Long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
private Classification classification;
|
private Classification classification;
|
||||||
private Map animals;
|
private Map directors = new HashMap();
|
||||||
private Map mammals;
|
private Map animals = new HashMap();
|
||||||
|
private Map mammals = new HashMap();
|
||||||
private Address address;
|
private Address address;
|
||||||
|
|
||||||
|
public Zoo() {
|
||||||
|
}
|
||||||
|
public Zoo(String name, Address address) {
|
||||||
|
this.name = name;
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +39,14 @@ public class Zoo {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map getDirectors() {
|
||||||
|
return directors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirectors(Map directors) {
|
||||||
|
this.directors = directors;
|
||||||
|
}
|
||||||
|
|
||||||
public Map getMammals() {
|
public Map getMammals() {
|
||||||
return mammals;
|
return mammals;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,4 +52,11 @@ public class JPAQLComplianceTest extends AbstractJPATest {
|
||||||
s.createQuery( "select c FROM Item c WHERE c.parts IS EMPTY" ).list();
|
s.createQuery( "select c FROM Item c WHERE c.parts IS EMPTY" ).list();
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testOrderByAlias() {
|
||||||
|
Session s = openSession();
|
||||||
|
s.createQuery( "select c.name as myname FROM Item c ORDER BY myname" ).list();
|
||||||
|
s.createQuery( "select p.name as name, p.stockNumber as stockNo, p.unitPrice as uPrice FROM Part p ORDER BY name, abs( p.unitPrice ), stockNo" ).list();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue