|
[
Permalink
| « Hide
]
Gavin King added a comment - 17/Mar/05 10:49 PM
A workaround is to define a SQLFunctionTemplate on a Dialect subclass
I need this function too (masking permission and quering for permitted objects in one shot).
Why it can't be standardize through all the dialect ? It's just a scalar function, could be andbit(a,b) and so on (orbit , xorbit). bit_or is another function in postgresql, of type aggregate, thus my covention. it can be standardized through the dialect just like Gavin wrote.
I vote for one standard naming convention for bitwise functions in Hibernate distribution standard dialects.
Here is how I implement bitwise function (and aggregate bitwise functions found in group by clause) for PostgreSQL 8.1, hibernate 3.1.2. Thank you for your work, hibernate community. import java.util.List; import org.hibernate.Hibernate; import org.hibernate.QueryException; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.engine.Mapping; import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.type.Type; /** * Implements bitwise varargs (max 4) functions for PostgreSQL. Overload bit_and * and bit_or functions using 1 arg as aggreagate bitwise function. */ public class PostgreSQLDialect extends org.hibernate.dialect.PostgreSQLDialect { public PostgreSQLDialect() { super(); registerFunction("bit_and", new SQLFunctionTemplates(Hibernate.INTEGER, "bit_and(?1)", "?1 & ?2 & ?3 & ?4")); registerFunction("bit_not", new SQLFunctionTemplate(Hibernate.INTEGER, "~?1")); registerFunction("bit_or", new SQLFunctionTemplates(Hibernate.INTEGER, "bit_or(?1)", "?1 & ?2 & ?3 & ?4")); } public static class SQLFunctionTemplates implements SQLFunction { private SQLFunctionTemplate template1arg; private SQLFunctionTemplate templateNarg; public SQLFunctionTemplates(Type type, String template1arg, String templateNarg) { this.template1arg = new SQLFunctionTemplate(type, template1arg); this.templateNarg = new SQLFunctionTemplate(type, templateNarg); } private SQLFunctionTemplate getSQLFunctionTemplate(List args) { if (args.size() == 1) return template1arg; return templateNarg; } public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { return template1arg.getReturnType(columnType, mapping); } public boolean hasArguments() { return true; } public boolean hasParenthesesIfNoArguments() { return true; } public String render(List args, SessionFactoryImplementor factory) throws QueryException { return getSQLFunctionTemplate(args).render(args, factory); } } } Sorry, error in bit_or function.
Here is the right line: (copied and pasted without changing & with |). registerFunction("bit_or", new SQLFunctionTemplates(Hibernate.INTEGER, "bit_or(?1)", "?1 | ?2 | ?3 | ?4")); To me it makes sense to include the bitwise operators as part of the syntax, rather than as functions, because then the correct operator precidence is available.
BTW: the registerFunction line for bit_and and bit_or can take advantage of org.hibernate.dialect.function.VarArgsSQLFunction.
Using this you can get rid of the inner class, and just do the following in the constructor: registerFunction("bit_not", new SQLFunctionTemplate(Hibernate.INTEGER, "~?1")); registerFunction("bit_and", new VarArgsSQLFunction(Hibernate.INTEGER, "(", "&", ")")); registerFunction("bit_or", new VarArgsSQLFunction(Hibernate.INTEGER, "(", "|", ")")); Note the additional surrounding brackets, this ensures the function-like behaviour rather than using the DB's operator precidence. |
||||||||||||||||||||||||||||||||||||||||||||||