HHH-5225 : Cannot parse order-by fragment if it contains a registered function without parentheses

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20197 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2010-08-19 23:06:32 +00:00
parent f881605577
commit 9ba97ec5cc
4 changed files with 49 additions and 11 deletions

View File

@ -717,11 +717,9 @@ private static boolean isFunction(String lcToken, String nextToken, SQLFunctionR
// lcToken does not refer to a function // lcToken does not refer to a function
return false; return false;
} }
// if function.hasArguments() and function.hasParenthesesIfNoArguments() is true, // if function.hasParenthesesIfNoArguments() is true, then assume
// then assume that lcToken is not a function, since it is not followed by "("; // lcToken is not a function (since it is not followed by '(')
// can't seem to use function.hasParenthesesIfNoArguments() alone because return ! function.hasParenthesesIfNoArguments();
// function definitions may return true if "()" is optional when there are no arguments.
return function.hasArguments() && function.hasParenthesesIfNoArguments() ? false : true;
} }
private static boolean isIdentifier(String token, Dialect dialect) { private static boolean isIdentifier(String token, Dialect dialect) {

View File

@ -103,7 +103,20 @@ protected AST quotedString(AST ident) {
* {@inheritDoc} * {@inheritDoc}
*/ */
protected boolean isFunctionName(AST ast) { protected boolean isFunctionName(AST ast) {
return context.getSqlFunctionRegistry().hasFunction( ast.getText() ); AST child = ast.getFirstChild();
// assume it is a function if it has parameters
if ( child != null && "{param list}".equals( child.getText() ) ) {
return true;
}
final SQLFunction function = context.getSqlFunctionRegistry().findSQLFunction( ast.getText() );
if ( function == null ) {
return false;
}
// if function.hasParenthesesIfNoArguments() is true, then assume
// ast.getText() is not a function.
return ! function.hasParenthesesIfNoArguments();
} }
/** /**
@ -111,8 +124,10 @@ protected boolean isFunctionName(AST ast) {
*/ */
protected AST resolveFunction(AST ast) { protected AST resolveFunction(AST ast) {
AST child = ast.getFirstChild(); AST child = ast.getFirstChild();
if ( child != null ) {
assert "{param list}".equals( child.getText() ); assert "{param list}".equals( child.getText() );
child = child.getFirstChild(); child = child.getFirstChild();
}
final String functionName = ast.getText(); final String functionName = ast.getText();
final SQLFunction function = context.getSqlFunctionRegistry().findSQLFunction( functionName ); final SQLFunction function = context.getSqlFunctionRegistry().findSQLFunction( functionName );

View File

@ -37,6 +37,8 @@
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Restrictions;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.testing.junit.functional.FunctionalTestCase; import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite; import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
@ -196,6 +198,13 @@ public void testGetMultiColumnSameNameAsArgFunctionCriteria() {
} }
public void testGetMultiColumnSameNameAsNoArgFunctionHQL() throws Exception { public void testGetMultiColumnSameNameAsNoArgFunctionHQL() throws Exception {
SQLFunction function =
( ( SessionFactoryImplementor ) getSessions() ).getSqlFunctionRegistry().findSQLFunction( "current_date" );
if ( function == null || function.hasParenthesesIfNoArguments() ) {
reportSkip( "current_date reuires ()", "tests noarg function that does not require ()" );
return;
}
Session s = openSession(); Session s = openSession();
Transaction t = s.beginTransaction(); Transaction t = s.beginTransaction();
EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn(); EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn();
@ -235,6 +244,13 @@ public void testGetMultiColumnSameNameAsNoArgFunctionHQL() throws Exception {
} }
public void testGetMultiColumnSameNameAsNoArgFunctionCriteria() { public void testGetMultiColumnSameNameAsNoArgFunctionCriteria() {
SQLFunction function =
( ( SessionFactoryImplementor ) getSessions() ).getSqlFunctionRegistry().findSQLFunction( "current_date" );
if ( function == null || function.hasParenthesesIfNoArguments() ) {
reportSkip( "current_date reuires ()", "tests noarg function that does not require ()" );
return;
}
Session s = openSession(); Session s = openSession();
Transaction t = s.beginTransaction(); Transaction t = s.beginTransaction();
EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn(); EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn();
@ -274,6 +290,13 @@ public void testGetMultiColumnSameNameAsNoArgFunctionCriteria() {
} }
public void testNoArgFcnAndColumnSameNameAsNoArgFunctionHQL() { public void testNoArgFcnAndColumnSameNameAsNoArgFunctionHQL() {
SQLFunction function =
( ( SessionFactoryImplementor ) getSessions() ).getSqlFunctionRegistry().findSQLFunction( "current_date" );
if ( function == null || function.hasParenthesesIfNoArguments() ) {
reportSkip( "current_date reuires ()", "tests noarg function that does not require ()" );
return;
}
Session s = openSession(); Session s = openSession();
Transaction t = s.beginTransaction(); Transaction t = s.beginTransaction();
EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn(); EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn();

View File

@ -9,11 +9,13 @@
<generator class="increment"/> <generator class="increment"/>
</id> </id>
<many-to-one name="nextHolder" cascade="all"/> <many-to-one name="nextHolder" cascade="all"/>
<set name="entityWithArgFunctionAsColumns" inverse="false" lazy="true" cascade="all-delete-orphan"> <set name="entityWithArgFunctionAsColumns" inverse="false" lazy="true" cascade="all-delete-orphan"
order-by="lower,lower( upper )">
<key column="HOLDER_ID"/> <key column="HOLDER_ID"/>
<one-to-many class="EntityWithArgFunctionAsColumn"/> <one-to-many class="EntityWithArgFunctionAsColumn"/>
</set> </set>
<set name="entityWithNoArgFunctionAsColumns" inverse="false" lazy="true" cascade="all-delete-orphan"> <set name="entityWithNoArgFunctionAsColumns" inverse="false" lazy="true" cascade="all-delete-orphan"
order-by="current_date, `current_date`">
<key column="HOLDER_ID"/> <key column="HOLDER_ID"/>
<one-to-many class="EntityWithNoArgFunctionAsColumn"/> <one-to-many class="EntityWithNoArgFunctionAsColumn"/>
</set> </set>