-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Possible bug in PostgresSQLDialect?
PostPosted: Sun Aug 31, 2008 1:56 pm 
Newbie

Joined: Sun Sep 11, 2005 3:28 am
Posts: 8
Hibernate version: 3.2.5.ga
Name and version of the database you are using: Postgres 8.3

Code:
"from Tag t order by rand()"

works fine when run against hsqldb but fails against postgres. I've turned on hibernate logging and the generated sql ends with "order by rand()" in both cases, however postgres doesn't have a rand() function - it uses random() instead.

The PostgresSQLDialect class contains the line

Code:
registerFunction( "random", new NoArgSQLFunction("random", Hibernate.DOUBLE) );


I'm not 100% sure how the dialects work, but suspect this should be

Code:
registerFunction( "rand", new NoArgSQLFunction("random", Hibernate.DOUBLE) );


Certainly when I extend the dialect as follows my hql statement works in both hsqldb and postgres environments.

Code:
class CustomPostgresSQLDialect extends PostgreSQLDialect {
    CustomPostgresSQLDialect() {
        super()
        registerFunction( "rand", new NoArgSQLFunction("random", Hibernate.DOUBLE) );
    }
}


Is this a bug or am I doing something daft?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 31, 2008 3:03 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I would not say it is a bug. I think Hibernate developers has deliberately chosen to register custom SQL functions with the same name as are used in the underlying database. If you look around you will find plenty of examples. Here is one more:

In MySQL the log() function returns the natural logarithm of the argument, but in PostgreSQL it returns the 10-based logarithm. ln() returns the natural logarithm in both database. To get 10-based logarithm with MySQL you need to use log10().

In other words, if you want a database-independent application when using non-standardized functionality you need to implement some kind of dialect-like functionality. In our project we have a simple interface for everything we need. For example:

Code:
/**
Get SQL/HQL for calculating natural logarithm.
*/
public String ln(String arg);


Top
 Profile  
 
 Post subject: Maybe, but not convinced...
PostPosted: Sun Aug 31, 2008 4:28 pm 
Newbie

Joined: Sun Sep 11, 2005 3:28 am
Posts: 8
I hear what you're saying and agree that a different approach (such as the one you proposed) is required if you have a complex SQL statement which is considerably different because db specific functionality, but in the case where calling rand() in an HQL statement will work in almost all dialects, but not postgres because the authors happend to name the function "random", surely it would make sense to map them to the same HQL function name?

Even gavin king suggests using the rand() function in HQL

http://www.mail-archive.com/hibernate-d ... 02820.html

Also you'll find other examples like the following where the underlying db's ltrim and rtrim functions have been combined and assigned to an HQL "trim" function. The only reason I can see for this is to ensure that the HQL trim function is available and consistent in as many dialects as possible.

Code:
registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") );


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 01, 2008 1:46 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I was just trying to suggest an alternate solution. I don't consider this a bug. If you want to support different databases you will run into problems with differences that Hibernate doesn't solve for you.

Another solution is to register the function in your Configuration object before you call Configuration.buildSessionFactory().

Code:
Configuration.addSqlRunction("rand", new NoArgSQLFunction("random", Hibernate.DOUBLE));


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.