From 9ba97ec5ccfab24c0ed128abc5415950a5b17867 Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Thu, 19 Aug 2010 23:06:32 +0000 Subject: [PATCH] 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 --- .../main/java/org/hibernate/sql/Template.java | 8 +++---- .../ordering/antlr/OrderByFragmentParser.java | 21 ++++++++++++++--- .../test/hql/FunctionNameAsColumnTest.java | 23 +++++++++++++++++++ .../test/hql/FunctionNamesAsColumns.hbm.xml | 8 ++++--- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/hibernate/sql/Template.java b/core/src/main/java/org/hibernate/sql/Template.java index ce5302f10e..8865b88eb5 100644 --- a/core/src/main/java/org/hibernate/sql/Template.java +++ b/core/src/main/java/org/hibernate/sql/Template.java @@ -717,11 +717,9 @@ private static boolean isFunction(String lcToken, String nextToken, SQLFunctionR // lcToken does not refer to a function return false; } - // if function.hasArguments() and function.hasParenthesesIfNoArguments() is true, - // then assume that lcToken is not a function, since it is not followed by "("; - // can't seem to use function.hasParenthesesIfNoArguments() alone because - // function definitions may return true if "()" is optional when there are no arguments. - return function.hasArguments() && function.hasParenthesesIfNoArguments() ? false : true; + // if function.hasParenthesesIfNoArguments() is true, then assume + // lcToken is not a function (since it is not followed by '(') + return ! function.hasParenthesesIfNoArguments(); } private static boolean isIdentifier(String token, Dialect dialect) { diff --git a/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java b/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java index 53683ebfc3..c7b0ed79e0 100644 --- a/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java +++ b/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java @@ -103,7 +103,20 @@ protected AST quotedString(AST ident) { * {@inheritDoc} */ 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) { AST child = ast.getFirstChild(); - assert "{param list}".equals( child.getText() ); - child = child.getFirstChild(); + if ( child != null ) { + assert "{param list}".equals( child.getText() ); + child = child.getFirstChild(); + } final String functionName = ast.getText(); final SQLFunction function = context.getSqlFunctionRegistry().findSQLFunction( functionName ); diff --git a/testsuite/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java b/testsuite/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java index 3c71300b53..7933ccf95f 100644 --- a/testsuite/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java +++ b/testsuite/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java @@ -37,6 +37,8 @@ import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; 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.FunctionalTestClassTestSuite; @@ -196,6 +198,13 @@ public void testGetMultiColumnSameNameAsArgFunctionCriteria() { } 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(); Transaction t = s.beginTransaction(); EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn(); @@ -235,6 +244,13 @@ public void testGetMultiColumnSameNameAsNoArgFunctionHQL() throws Exception { } 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(); Transaction t = s.beginTransaction(); EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn(); @@ -274,6 +290,13 @@ public void testGetMultiColumnSameNameAsNoArgFunctionCriteria() { } 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(); Transaction t = s.beginTransaction(); EntityWithNoArgFunctionAsColumn e1 = new EntityWithNoArgFunctionAsColumn(); diff --git a/testsuite/src/test/java/org/hibernate/test/hql/FunctionNamesAsColumns.hbm.xml b/testsuite/src/test/java/org/hibernate/test/hql/FunctionNamesAsColumns.hbm.xml index 454a60d030..85fa4019d3 100644 --- a/testsuite/src/test/java/org/hibernate/test/hql/FunctionNamesAsColumns.hbm.xml +++ b/testsuite/src/test/java/org/hibernate/test/hql/FunctionNamesAsColumns.hbm.xml @@ -9,11 +9,13 @@ - + - + @@ -31,7 +33,7 @@ - + \ No newline at end of file