HHH-11957 : DB2 substring method needs to be exposed in DB297Dialect

This commit is contained in:
Gail Badner 2017-09-01 15:34:30 -07:00
parent 385a18b11b
commit 80937ee583
3 changed files with 64 additions and 1 deletions

View File

@ -6,11 +6,14 @@
*/
package org.hibernate.dialect;
import org.hibernate.dialect.function.DB2SubstringFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.hql.spi.id.local.LocalTemporaryTableBulkIdStrategy;
import org.hibernate.type.StandardBasicTypes;
/**
* An SQL dialect for DB2 9.7.
@ -19,6 +22,11 @@ import org.hibernate.hql.spi.id.local.LocalTemporaryTableBulkIdStrategy;
*/
public class DB297Dialect extends DB2Dialect {
public DB297Dialect() {
super();
registerFunction( "substring", new DB2SubstringFunction() );
}
@Override
public String getCrossJoinSeparator() {
// DB2 9.7 and later support "cross join"

View File

@ -0,0 +1,51 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect.function;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.type.StandardBasicTypes;
/**
* When "substring" function is used for DB2, this implementation of {@link StandardSQLFunction}
* will render "substr" or "substring", depending on the last argument being used. If the last
* argument is a string unit ("CODEUNITS16", "CODEUNITS32", or "OCTETS"), then the function
* will be rendered as "substring"; otherwise, it will be rendered as "substr".
* <p/>
* ANSI SQL-92 standard defines "substring" without string units, which is more similar to DB2's "substr",
* so it makes sense to use DB2's "substr" function when string units are not provided.
* <p/>
* Background: DB2 has both "substr" and "substring", which are different functions that are not
* interchangeable. Prior to DB2 11.1, DB2's "substring" function requires an argument for string
* units; without this argument, DB2 throws an exception. DB2's "substr" function throws an exception
* if string unit is provided as an argument.
*
* @author Gail Badner
*/
public class DB2SubstringFunction extends StandardSQLFunction {
private static final Set<String> possibleStringUnits = new HashSet<>(
Arrays.asList( "CODEUNITS16", "CODEUNITS32", "OCTETS" )
);
public DB2SubstringFunction() {
super( "substring", StandardBasicTypes.STRING );
}
@Override
protected String getRenderedName(List arguments) {
final String lastArgument = (String) arguments.get( arguments.size() - 1 );
if ( lastArgument != null && possibleStringUnits.contains( lastArgument.toUpperCase() ) ) {
return getName();
}
else{
return "substr";
}
}
}

View File

@ -86,7 +86,7 @@ public class StandardSQLFunction implements SQLFunction {
@Override
public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
final StringBuilder buf = new StringBuilder();
buf.append( name ).append( '(' );
buf.append( getRenderedName( arguments) ).append( '(' );
for ( int i = 0; i < arguments.size(); i++ ) {
buf.append( arguments.get( i ) );
if ( i < arguments.size() - 1 ) {
@ -96,6 +96,10 @@ public class StandardSQLFunction implements SQLFunction {
return buf.append( ')' ).toString();
}
protected String getRenderedName(List arguments) {
return getName();
}
@Override
public String toString() {
return name;