Fix CriteriaBuidler#locate() arguments order rendering

This commit is contained in:
Andrea Boriero 2022-01-18 09:14:41 +01:00 committed by Christian Beikov
parent 370d9354fc
commit b8fab567cc
15 changed files with 65 additions and 83 deletions

View File

@ -170,10 +170,10 @@ public class CacheDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"$find(?1,?2)",
"$find(?1,?2,?3)",
"$find(?2,?1)",
"$find(?2,?1,?3)",
STRING, STRING, INTEGER
).setArgumentListSignature("(string, pattern[, start])");
).setArgumentListSignature("(pattern, string[, start])");
CommonFunctionFactory.bitLength_pattern( queryEngine, "($length(?1)*8)" );
useJdbcEscape(queryEngine, "sin");

View File

@ -276,15 +276,15 @@ public class FirebirdDialect extends Dialect {
CommonFunctionFactory.reverse( queryEngine );
CommonFunctionFactory.bitandorxornot_binAndOrXorNot( queryEngine );
CommonFunctionFactory.leastGreatest_minMaxValue( queryEngine );
SqmFunctionRegistry functionRegistry = queryEngine.getSqmFunctionRegistry();
SqmFunctionRegistry functionRegistry = queryEngine.getSqmFunctionRegistry();
functionRegistry.registerBinaryTernaryPattern(
"locate",
integerType,
"position(?2 in ?1)",
"position(?2,?1,?3)",
"position(?1 in ?2)",
"position(?1,?2,?3)",
STRING, STRING, INTEGER
).setArgumentListSignature( "(string, pattern[, start])" );
).setArgumentListSignature( "(pattern, string[, start])" );
functionRegistry.namedDescriptorBuilder( "ascii_val" )
.setExactArgumentCount( 1 )
.setInvariantType( shortType )

View File

@ -181,14 +181,7 @@ public class InformixDialect extends Dialect {
CommonFunctionFactory.monthsBetween( queryEngine );
CommonFunctionFactory.stddev( queryEngine );
CommonFunctionFactory.variance( queryEngine );
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"instr(?1,?2)",
"instr(?1,?2,?3)",
STRING, STRING, INTEGER
).setArgumentListSignature("(string, pattern[, start])");
CommonFunctionFactory.locate_positionSubstring( queryEngine );
//coalesce() and nullif() both supported since Informix 12

View File

@ -279,10 +279,16 @@ public class IngresDialect extends Dialect {
CommonFunctionFactory.format_dateFormat( queryEngine );
CommonFunctionFactory.dateTrunc( queryEngine );
CommonFunctionFactory.bitLength_pattern( queryEngine, "octet_length(hex(?1))*4" );
CommonFunctionFactory.locate_positionSubstring( queryEngine );
final BasicType<Integer> integerType = queryEngine.getTypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
integerType,
"position(?1 in ?2)",
"(position(?1 in substring(?2 from ?3))+(?3)-1)",
STRING, STRING, INTEGER
).setArgumentListSignature("(pattern, string[, start])");
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "date_part('?1',?2)", integerType );

View File

@ -166,9 +166,9 @@ public class MaxDBDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
integerType, "index(?1,?2)", "index(?1,?2,?3)",
integerType, "index(?2,?1)", "index(?2,?1,?3)",
STRING, STRING, INTEGER
).setArgumentListSignature("(string, pattern[, start])");
).setArgumentListSignature("(pattern, string[, start])");
}
@Override

View File

@ -274,10 +274,10 @@ public class SQLiteDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
integerType,
"instr(?1,?2)",
"instr(?1,?2,?3)",
"instr(?2,?1)",
"instr(?2,?1,?3)",
STRING, STRING, INTEGER
).setArgumentListSignature("(string, pattern[, start])");
).setArgumentListSignature("(pattern, string[, start])");
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"lpad",
stringType,

View File

@ -170,10 +170,10 @@ public class TimesTenDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"instr(?1,?2)",
"instr(?1,?2,?3)",
"instr(?2,?1)",
"instr(?2,?1,?3)",
STRING, STRING, INTEGER
).setArgumentListSignature("(string, pattern[, start])");
).setArgumentListSignature("(pattern, string[, start])");
}
@Override

View File

@ -277,10 +277,10 @@ public abstract class AbstractHANADialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"locate(?1,?2)",
"locate(?1,?2,?3)",
"locate(?2,?1)",
"locate(?2,?1,?3)",
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
).setArgumentListSignature("(string, pattern[, start])");
).setArgumentListSignature("(pattern, string[, start])");
CommonFunctionFactory.ceiling_ceil( queryEngine );
CommonFunctionFactory.concat_pipeOperator( queryEngine );

View File

@ -184,10 +184,10 @@ public class OracleDialect extends Dialect {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"instr(?1,?2)",
"instr(?1,?2,?3)",
"instr(?2,?1)",
"instr(?2,?1,?3)",
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
).setArgumentListSignature("(string, pattern[, start])");
).setArgumentListSignature("(pattern, string[, start])");
}
@Override

View File

@ -449,13 +449,7 @@ public class PostgreSQLDialect extends Dialect {
CommonFunctionFactory.overlay( queryEngine );
CommonFunctionFactory.soundex( queryEngine ); //was introduced in Postgres 9 apparently
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"position(?2 in ?1)",
"(position(?2 in substring(?1 from ?3))+(?3)-1)",
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
).setArgumentListSignature("(string, pattern[, start])");
CommonFunctionFactory.locate_positionSubstring( queryEngine );
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
CommonFunctionFactory.makeDateTimeTimestamp( queryEngine );

View File

@ -1548,40 +1548,29 @@ public class CommonFunctionFactory {
}
public static void locate(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"locate(?2,?1)",
"locate(?2,?1,?3)",
STRING,
STRING,
INTEGER
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "locate" )
.setInvariantType(
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
)
.setArgumentListSignature( "(STRING string, STRING pattern[, INTEGER start])" );
.setArgumentCountBetween( 2, 3 )
.setParameterTypes(STRING, STRING, INTEGER)
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" )
.register();
}
/**
* Transact SQL-style
*/
public static void locate_charindex(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"charindex(?2,?1)",
"charindex(?2,?1,?3)",
STRING,
STRING,
INTEGER
).setArgumentListSignature( "(STRING string, STRING pattern[, INTEGER start])" );
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "charindex" )
.setInvariantType(
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
)
.setArgumentCountBetween( 2, 3 )
.setParameterTypes( STRING, STRING, INTEGER )
.setParameterTypes(STRING, STRING, INTEGER)
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" )
.register();
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "locate", "charindex" );
}
/**
@ -1591,10 +1580,10 @@ public class CommonFunctionFactory {
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
"locate",
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
"position(?2 in ?1)", "(position(?2 in substring(?1 from ?3))+?3)",
"position(?1 in ?2)", "(position(?1 in substring(?2 from ?3))+(?3)-1)",
STRING, STRING, INTEGER
)
.setArgumentListSignature( "(STRING string, STRING pattern[, INTEGER start])" );
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" );
}
/**
* ANSI-style substring

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.dialect.function;
import org.hibernate.mapping.Collection;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
@ -18,8 +17,6 @@ import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
@ -45,18 +42,6 @@ public class LocatePositionEmulation extends AbstractSqmFunctionDescriptor {
ReturnableType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
if ( arguments instanceof ArrayList ) {
Collections.swap( arguments, 0, 1 );
}
else {
List<SqmTypedNode<?>> argumentTemp = new ArrayList<>( arguments.size() );
argumentTemp.add( arguments.get( 1 ) );
argumentTemp.add( arguments.get( 0 ) );
for ( int i = 2; i < arguments.size(); i++ ) {
argumentTemp.add( arguments.get( i ) );
}
arguments = argumentTemp;
}
return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor( "locate" )
.generateSqmExpression( arguments, impliedResultType, queryEngine, typeConfiguration );
}

View File

@ -1255,14 +1255,14 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
final List<SqmTypedNode<?>> arguments;
if ( startPosition == null ) {
arguments = asList(
source,
pattern
);
pattern,
source
);
}
else {
arguments = asList(
source,
pattern,
source,
startPosition
);
}

View File

@ -26,9 +26,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Jpa(
annotatedClasses = CriteriaLocateTest.Person.class
annotatedClasses = LocateTest.Person.class
)
public class CriteriaLocateTest {
public class LocateTest {
@BeforeEach
public void setUp(EntityManagerFactoryScope scope) {
@ -112,6 +112,21 @@ public class CriteriaLocateTest {
);
}
@Test
public void locateQueryTest(EntityManagerFactoryScope scope) {
scope.inTransaction(
entityManager -> {
final List<Integer> ids = entityManager.createQuery(
"select distinct p.id from Person p where locate('nd', p.name) = 2" )
.getResultList();
assertEquals( 2, ids.size() );
assertTrue( ids.contains( 3 ) );
assertTrue( ids.contains( 4 ) );
}
);
}
@Entity(name = "Person")
@Table(name = "PERSON_TABLE")
public static class Person {

View File

@ -407,11 +407,11 @@ public class FunctionTests {
public void testLocateFunction(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
session.createQuery("select locate( e.theString, 'hello') from EntityOfBasics e")
session.createQuery("select locate('hello', e.theString) from EntityOfBasics e")
.list();
session.createQuery("select locate( e.theString, 'hello', e.theInteger) from EntityOfBasics e")
session.createQuery("select locate('hello', e.theString, e.theInteger) from EntityOfBasics e")
.list();
assertThat( session.createQuery("select locate( 'hello world', 'world')").getSingleResult(), is(7) );
assertThat( session.createQuery("select locate('world', 'hello world')").getSingleResult(), is(7) );
}
);
}