Hi,
I am trying to understand the logic behind an observation:
In hibernate 5.6 functions are registered as:
public PostgresPlusDialect() {
super();
registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
registerFunction( "soundex", new StandardSQLFunction( "soundex" ) );
registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.DATE, false ) );
registerFunction( "rowid", new NoArgSQLFunction( "rowid", StandardBasicTypes.LONG, false ) );
registerFunction( "rownum", new NoArgSQLFunction( "rownum", StandardBasicTypes.LONG, false ) );
registerFunction( "instr", new StandardSQLFunction( "instr", StandardBasicTypes.INTEGER ) );
registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) );
registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) );
registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) );
registerFunction( "translate", new StandardSQLFunction( "translate", StandardBasicTypes.STRING ) );
registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) );
registerFunction( "coalesce", new NvlFunction() );
registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.FLOAT ) );
registerFunction( "mod", new StandardSQLFunction( "mod", StandardBasicTypes.INTEGER ) );
registerFunction( "nvl", new StandardSQLFunction( "nvl" ) );
registerFunction( "nvl2", new StandardSQLFunction( "nvl2" ) );
registerFunction( "power", new StandardSQLFunction( "power", StandardBasicTypes.FLOAT ) );
registerFunction( "add_months", new StandardSQLFunction( "add_months", StandardBasicTypes.DATE ) );
registerFunction( "months_between", new StandardSQLFunction( "months_between", StandardBasicTypes.FLOAT ) );
registerFunction( "next_day", new StandardSQLFunction( "next_day", StandardBasicTypes.DATE ) );
}
But in hibernate 6.1, it seems these functions are moved to its parent class by providing
CommonFunctionFactory class and registered these functions as:
@Override
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
super.initializeFunctionRegistry(functionContributions);
CommonFunctionFactory functionFactory = new CommonFunctionFactory(functionContributions);
functionFactory.soundex();
functionFactory.rownumRowid();
functionFactory.sysdate();
functionFactory.systimestamp();
// queryEngine.getSqmFunctionRegistry().register( "coalesce", new NvlCoalesceEmulation() );
}
When I called for example MEDIAN
function as
scope.inTransaction( session -> {
sqlStatementInspector.clear();
assertEquals(
1.78d,
session.createQuery(
String.format( "select median(h.bigDecimalValue) from Human h", function ),
BigDecimal.class
).getSingleResult()
);
Hibernate logs show it as mapped to percentile_cont(0.5)
function:
15:15:24,279 DEBUG SQL:128 -
select
percentile_cont(0.5) within
group (order by
h1_0.bigDecimalValue)
from
Human h1_0
But when I called INSTR
function, it is shown as:
15:09:57,128 DEBUG SQL:128 -
select
instr('Tech on the net','e')
I checked in PostgreSQLDialect which is direct parent class of PostgresPlusDialect and did not find in the initializeFunctionRegistry.
May I know how PostgresPlustDialect knows that instr function is added to function registry?
And how it knows that MEDIAN needs to map to percentile_cont(0.5) which actually an equivalent function in PostgreSQL database?
I am using Postgres Advanced server as backend database.
Thanks,
Affaan