package org.infinispan.query.dsl.embedded.impl;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
import java.util.Map;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.hibernate.search.engine.integration.impl.ExtendedSearchIntegrator;
import org.hibernate.search.exception.SearchException;
import org.hibernate.search.testsupport.junit.SearchFactoryHolder;
import org.infinispan.objectfilter.ParsingException;
import org.infinispan.objectfilter.impl.syntax.parser.IckleParsingResult;
import org.infinispan.objectfilter.impl.syntax.parser.IckleParser;
import org.infinispan.objectfilter.impl.syntax.parser.ReflectionEntityNamesResolver;
import org.infinispan.query.dsl.embedded.impl.model.Employee;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
/**
* Test the parsing and transformation of Ickle queries to Lucene queries.
*
* @author anistor@redhat.com
* @since 9.0
*/
public class LuceneTransformationTest {
@Rule
public SearchFactoryHolder factoryHolder = new SearchFactoryHolder(Employee.class);
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void testRaiseExceptionDueToUnknownAlias() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028502: Unknown alias: a.");
parseAndTransform("from org.infinispan.query.dsl.embedded.impl.model.Employee e where a.name = 'same'");
}
@Test
public void testMatchAllQuery() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee",
"*:*");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e",
"*:*");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e",
"*:*");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where true",
"*:*");
}
@Test
public void testRejectAllQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where false",
"-*:* #*:*"); //TODO [anistor] maybe this should be "-*:*"
}
@Test
public void testFullTextKeyword() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : 'bicycle'",
"text:bicycle");
}
@Test
public void testFullTextWildcard() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : 'geo*e'",
"text:geo*e");
}
@Test
public void testFullTextFuzzy() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : 'jonh'~2",
"text:jonh~2");
}
@Test
public void testFullTextPhrase() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : 'twisted cables'",
"text:\"twisted cables\"");
}
@Test
public void testFullTextRegexp() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : /te?t/",
"text:/te?t/");
}
@Test
public void testFullTextRange() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : ['AAA' 'ZZZ']",
"text:[aaa TO zzz]");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : ['AAA' to 'ZZZ']",
"text:[aaa TO zzz]");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : [* to 'eeee']",
"text:[* TO eeee]");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : ['eeee' to *]",
"text:[eeee TO *]");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : [* *]",
"text:[* TO *]");
}
@Test
public void testFullTextFieldBoost() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : 'foo'^3.0'",
"text:foo^3.0");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : ('foo')^3.0'",
"text:foo^3.0");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : ('foo' and 'bar')^3.0'",
"(+text:foo +text:bar)^3.0");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : 'foo'^3.0 || e.analyzedInfo : 'bar'",
"text:foo^3.0 analyzedInfo:bar");
}
@Test
public void testFullTextFieldOccur() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : (-'foo') ",
"-text:foo #*:*");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : (-'foo' +'bar')",
"(-text:foo) (+text:bar)");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where not e.text : (-'foo' +'bar')",
"-((-text:foo) (+text:bar)) #*:*");
// TODO [anistor] fix this
// assertGeneratedLuceneQuery(
// "from org.infinispan.query.dsl.embedded.impl.model.Employee e where !e.text : (-'foo' +'bar')",
// "-((-text:foo) (+text:bar)) #*:*");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text : (-'foo' '*')",
"(-text:foo) text:*");
}
@Test
public void testRestrictedQueryUsingSelect() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' or e.id = 5",
"name:same id:5");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' and e.id = 5",
"+name:same +id:5");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' and not e.id = 5",
"+name:same -id:5");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' or not e.id = 5",
"name:same (-id:5 #*:*)");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where not e.id = 5",
"-id:5 #*:*");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.id != 5",
"-id:5 #*:*");
}
@Test
public void testFieldMapping() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.someMoreInfo = 'foo'",
"someMoreInfo:foo");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.sameInfo = 'foo'",
"sameInfo:foo");
}
@Test
public void testWrongFieldName() {
expectedException.expect(SearchException.class);
expectedException.expectMessage("Unable to find field otherInfo in org.infinispan.query.dsl.embedded.impl.model.Employee");
parseAndTransform("from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.otherInfo = 'foo'");
}
@Test
public void testProjectionQuery() {
LuceneQueryParsingResult<Class<?>> parsingResult = parseAndTransform("select e.id, e.name from org.infinispan.query.dsl.embedded.impl.model.Employee e");
assertThat(parsingResult.getQuery().toString()).isEqualTo("*:*");
assertThat(parsingResult.getProjections()).isEqualTo(new String[]{"id", "name"});
}
@Test
public void testEmbeddedProjectionQuery() {
LuceneQueryParsingResult<Class<?>> parsingResult = parseAndTransform("select e.author.name from org.infinispan.query.dsl.embedded.impl.model.Employee e");
assertThat(parsingResult.getQuery().toString()).isEqualTo("*:*");
assertThat(parsingResult.getProjections()).isEqualTo(new String[]{"author.name"});
}
@Test
public void testNestedEmbeddedProjectionQuery() {
LuceneQueryParsingResult<Class<?>> parsingResult = parseAndTransform("select e.author.address.street from org.infinispan.query.dsl.embedded.impl.model.Employee e");
assertThat(parsingResult.getQuery().toString()).isEqualTo("*:*");
assertThat(parsingResult.getProjections()).isEqualTo(new String[]{"author.address.street"});
}
@Test
public void testQueryWithUnqualifiedPropertyReferences() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where name = 'same' and not id = 5",
"+name:same -id:5");
}
@Test
public void testNegatedQuery() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where NOT e.name = 'same'",
"-name:same #*:*");
// JPQL syntax
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name <> 'same'",
"-name:same #*:*");
// HQL syntax
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name != 'same'",
"-name:same #*:*");
}
@Test
public void testNegatedQueryOnNumericProperty() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position <> 3",
"-position:[3 TO 3] #*:*");
}
@Test
public void testNegatedRangeQuery() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee where name = 'Bob' and not position between 1 and 3",
"+name:Bob -position:[1 TO 3]");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'Bob' and not e.position between 1 and 3",
"+name:Bob -position:[1 TO 3]");
}
@Test
public void testQueryWithNamedParameter() {
Map<String, Object> namedParameters = new HashMap<>();
namedParameters.put("nameParameter", "Bob");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee where name = :nameParameter",
namedParameters,
"name:Bob");
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = :nameParameter",
namedParameters,
"name:Bob");
}
@Test
public void testBooleanQuery() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' or (e.id = 4 and e.name = 'Bob')",
"name:same (+id:4 +name:Bob)");
}
@Test
public void testBooleanQueryUsingSelect() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' or (e.id = 4 and e.name = 'Bob')",
"name:same (+id:4 +name:Bob)");
}
@Test
public void testBetweenQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name between 'aaa' and 'zzz'",
"name:[aaa TO zzz]");
}
@Test
public void testNotBetweenQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name not between 'aaa' and 'zzz'",
"-name:[aaa TO zzz] #*:*");
}
@Test
public void testNumericNotBetweenQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where not e.position between 1 and 3",
"-position:[1 TO 3] #*:*");
}
@Test
public void testBetweenQueryForCharacterLiterals() {
assertGeneratedLuceneQuery("select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name between 'a' and 'z'", "name:[a TO z]");
}
@Test
public void testBetweenQueryWithNamedParameters() {
Map<String, Object> namedParameters = new HashMap<>();
namedParameters.put("p1", "aaa");
namedParameters.put("p2", "zzz");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name between :p1 and :p2",
namedParameters,
"name:[aaa TO zzz]");
}
@Test
public void testNumericBetweenQuery() {
Map<String, Object> namedParameters = new HashMap<>();
namedParameters.put("p1", 10L);
namedParameters.put("p2", 20L);
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position between :p1 and :p2",
namedParameters,
"position:[10 TO 20]");
}
@Test
public void testQueryWithEmbeddedPropertyInFromClause() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.author.name = 'Bob'",
"author.name:Bob");
}
@Test
public void testLessThanQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position < 100",
"position:[* TO 100}");
}
@Test
public void testLessThanOrEqualsToQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position <= 100",
"position:[* TO 100]");
}
@Test
public void testGreaterThanOrEqualsToQuery() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee where position >= 100",
"position:[100 TO *]");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position >= 100",
"position:[100 TO *]");
}
@Test
public void testGreaterThanQuery() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee where position > 100",
"position:{100 TO *]");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position > 100",
"position:{100 TO *]");
}
@Test
public void testInQuery() {
assertGeneratedLuceneQuery(
"from org.infinispan.query.dsl.embedded.impl.model.Employee where name in ('Bob', 'Alice')",
"name:Bob name:Alice");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name in ('Bob', 'Alice')",
"name:Bob name:Alice");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position in (10, 20, 30, 40)",
"position:[10 TO 10] position:[20 TO 20] position:[30 TO 30] position:[40 TO 40]");
}
@Test
public void testInQueryWithNamedParameters() {
Map<String, Object> namedParameters = new HashMap<>();
namedParameters.put("name1", "Bob");
namedParameters.put("name2", "Alice");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name in (:name1, :name2)",
namedParameters,
"name:Bob name:Alice");
namedParameters = new HashMap<>();
namedParameters.put("pos1", 10);
namedParameters.put("pos2", 20);
namedParameters.put("pos3", 30);
namedParameters.put("pos4", 40);
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position in (:pos1, :pos2, :pos3, :pos4)",
namedParameters,
"position:[10 TO 10] position:[20 TO 20] position:[30 TO 30] position:[40 TO 40]");
}
@Test
public void testNotInQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name not in ('Bob', 'Alice')",
"-(name:Bob name:Alice) #*:*");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.position not in (10, 20, 30, 40)",
"-(position:[10 TO 10] position:[20 TO 20] position:[30 TO 30] position:[40 TO 40]) #*:*");
}
@Test
public void testLikeQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name LIKE 'Al_ce'",
"name:Al?ce");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name LIKE 'Ali%'",
"name:Ali*");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name LIKE 'Ali%%'",
"name:Ali**");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name LIKE '_l_ce'",
"name:?l?ce");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name LIKE '___ce'",
"name:???ce");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name LIKE '_%_ce'",
"name:?*?ce");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name LIKE 'Alice in wonderl%'",
"name:Alice in wonderl*");
}
@Test
public void testNotLikeQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name NOT LIKE 'Al_ce'",
"-name:Al?ce #*:*");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name NOT LIKE 'Ali%'",
"-name:Ali* #*:*");
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name NOT LIKE '_l_ce' and not (e.title LIKE '%goo' and e.position = '5')",
"-name:?l?ce -(+title:*goo +position:[5 TO 5]) #*:*");
}
@Test
public void testIsNullQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name IS null",
"name:_null_");
}
@Test
public void testIsNullQueryForEmbeddedEntity() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.author IS null",
"author:_null_");
}
@Test
public void testIsNotNullQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name IS NOT null",
"-name:_null_ #*:*");
}
@Test
public void testCollectionOfEmbeddableQuery() {
assertGeneratedLuceneQuery(
"select e from org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d WHERE d.email = 'ninja647@mailinator.com' ",
"contactDetails.email:ninja647@mailinator.com");
}
@Test
public void testCollectionOfEmbeddableInEmbeddedQuery() {
assertGeneratedLuceneQuery(
"SELECT e FROM org.infinispan.query.dsl.embedded.impl.model.Employee e "
+ " JOIN e.contactDetails d"
+ " JOIN d.address.alternatives as a "
+ "WHERE a.postCode = '90210' ",
"contactDetails.address.alternatives.postCode:90210");
}
@Test
public void testRaiseExceptionDueToUnknownQualifiedProperty() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028501: The type org.infinispan.query.dsl.embedded.impl.model.Employee has no property named 'foobar'.");
parseAndTransform("from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.foobar = 'same'");
}
@Test
public void testRaiseExceptionDueToUnknownUnqualifiedProperty() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028501: The type org.infinispan.query.dsl.embedded.impl.model.Employee has no property named 'foobar'.");
parseAndTransform("from org.infinispan.query.dsl.embedded.impl.model.Employee e where foobar = 'same'");
}
@Test
public void testRaiseExceptionDueToAnalyzedPropertyInFromClause() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028522: No relational queries can be applied to property 'text' in type org.infinispan.query.dsl.embedded.impl.model.Employee since the property is analyzed.");
parseAndTransform("from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.text = 'foo'");
}
@Test
public void testRaiseExceptionDueToUnknownPropertyInSelectClause() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028501: The type org.infinispan.query.dsl.embedded.impl.model.Employee has no property named 'foobar'.");
parseAndTransform("select e.foobar from org.infinispan.query.dsl.embedded.impl.model.Employee e");
}
@Test
public void testRaiseExceptionDueToUnknownPropertyInEmbeddedSelectClause() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028501: The type org.infinispan.query.dsl.embedded.impl.model.Employee has no property named 'foo'.");
parseAndTransform("select e.author.foo from org.infinispan.query.dsl.embedded.impl.model.Employee e");
}
@Test
public void testRaiseExceptionDueToSelectionOfCompleteEmbeddedEntity() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028503: Property author can not be selected from type org.infinispan.query.dsl.embedded.impl.model.Employee since it is an embedded entity.");
parseAndTransform("select e.author from org.infinispan.query.dsl.embedded.impl.model.Employee e");
}
@Test
public void testRaiseExceptionDueToUnqualifiedSelectionOfCompleteEmbeddedEntity() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028503: Property author can not be selected from type org.infinispan.query.dsl.embedded.impl.model.Employee since it is an embedded entity.");
parseAndTransform("select author from org.infinispan.query.dsl.embedded.impl.model.Employee e");
}
@Test
public void testDetermineTargetEntityType() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' and not e.id = 5");
assertThat(result.getTargetEntityMetadata()).isSameAs(Employee.class);
assertThat(result.getTargetEntityName()).isEqualTo("org.infinispan.query.dsl.embedded.impl.model.Employee");
result = parseAndTransform("select e from org.infinispan.query.dsl.embedded.impl.model.Employee e");
assertThat(result.getTargetEntityMetadata()).isSameAs(Employee.class);
assertThat(result.getTargetEntityName()).isEqualTo("org.infinispan.query.dsl.embedded.impl.model.Employee");
}
@Test
public void testBuildOneFieldSort() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' order by e.title");
Sort sort = result.getSort();
assertThat(sort).isNotNull();
assertThat(sort.getSort().length).isEqualTo(1);
assertThat(sort.getSort()[0].getField()).isEqualTo("title");
assertThat(sort.getSort()[0].getReverse()).isEqualTo(false);
assertThat(sort.getSort()[0].getType()).isEqualTo(SortField.Type.STRING);
}
@Test
public void testBuildTwoFieldsSort() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' order by e.title, e.position DESC");
Sort sort = result.getSort();
assertThat(sort).isNotNull();
assertThat(sort.getSort().length).isEqualTo(2);
assertThat(sort.getSort()[0].getField()).isEqualTo("title");
assertThat(sort.getSort()[0].getReverse()).isEqualTo(false);
assertThat(sort.getSort()[0].getType()).isEqualTo(SortField.Type.STRING);
assertThat(sort.getSort()[1].getField()).isEqualTo("position");
assertThat(sort.getSort()[1].getReverse()).isEqualTo(true);
assertThat(sort.getSort()[1].getType()).isEqualTo(SortField.Type.LONG);
}
@Test
public void testBuildSortForNullEncoding() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select e from org.infinispan.query.dsl.embedded.impl.model.Employee e order by e.code DESC");
Sort sort = result.getSort();
assertThat(sort).isNotNull();
assertThat(sort.getSort().length).isEqualTo(1);
assertThat(sort.getSort()[0].getField()).isEqualTo("code");
assertThat(sort.getSort()[0].getType()).isEqualTo(SortField.Type.LONG);
}
@Test
public void testRaiseExceptionDueToUnrecognizedSortDirection() {
expectedException.expect(ParsingException.class);
expectedException.expectMessage("ISPN028526: Invalid query: select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' order by e.title DESblah, e.name ASC;");
parseAndTransform("select e from org.infinispan.query.dsl.embedded.impl.model.Employee e where e.name = 'same' order by e.title DESblah, e.name ASC");
}
@Test
public void testBeAbleToJoinOnCollectionOfEmbedded() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select d.email from org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d");
assertThat(result.getQuery().toString()).isEqualTo("*:*");
assertThat(result.getProjections()).containsOnly("contactDetails.email");
}
@Test
public void testBeAbleToJoinOnCollectionOfEmbeddedWithEmbedded() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select d.email from org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d WHERE d.address.postCode='EA123'");
assertThat(result.getQuery().toString()).isEqualTo("contactDetails.address.postCode:EA123");
assertThat(result.getProjections()).containsOnly("contactDetails.email");
}
@Test
public void testBeAbleToJoinOnCollectionOfEmbeddedWithEmbeddedAndUseInOperator() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select d.email from org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d WHERE d.address.postCode IN ('EA123')");
assertThat(result.getQuery().toString()).isEqualTo("contactDetails.address.postCode:EA123");
assertThat(result.getProjections()).containsOnly("contactDetails.email");
}
@Test
public void testBeAbleToJoinOnCollectionOfEmbeddedWithEmbeddedAndUseBetweenOperator() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select d.email from org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d WHERE d.address.postCode BETWEEN '0000' AND 'ZZZZ'");
assertThat(result.getQuery().toString()).isEqualTo("contactDetails.address.postCode:[0000 TO ZZZZ]");
assertThat(result.getProjections()).containsOnly("contactDetails.email");
}
@Test
public void testBeAbleToJoinOnCollectionOfEmbeddedWithEmbeddedAndUseGreaterOperator() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("select d.email from org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d WHERE d.address.postCode > '0000'");
assertThat(result.getQuery().toString()).isEqualTo("contactDetails.address.postCode:{0000 TO *]");
assertThat(result.getProjections()).containsOnly("contactDetails.email");
}
@Test
public void testBeAbleToJoinOnCollectionOfEmbeddedWithEmbeddedAndUseLikeOperator() {
LuceneQueryParsingResult<Class<?>> parsingResult = parseAndTransform("select d.email from org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d WHERE d.address.postCode LIKE 'EA1%'");
assertThat(parsingResult.getQuery().toString()).isEqualTo("contactDetails.address.postCode:EA1*");
assertThat(parsingResult.getProjections()).containsOnly("contactDetails.email");
}
@Test
public void testBeAbleToProjectUnqualifiedField() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("SELECT name, text FROM org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d");
assertThat(result.getQuery().toString()).isEqualTo("*:*");
assertThat(result.getProjections()).containsOnly("name", "text");
}
@Test
public void testBeAbleToProjectUnqualifiedFieldAndQualifiedField() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("SELECT name, text, d.email FROM org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d");
assertThat(result.getQuery().toString()).isEqualTo("*:*");
assertThat(result.getProjections()).containsOnly("name", "text", "contactDetails.email");
}
@Test
public void testBeAbleToProjectQualifiedField() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform("SELECT e.name, e.text, d.email FROM org.infinispan.query.dsl.embedded.impl.model.Employee e JOIN e.contactDetails d");
assertThat(result.getQuery().toString()).isEqualTo("*:*");
assertThat(result.getProjections()).containsOnly("name", "text", "contactDetails.email");
}
@Test
public void testBeAbleToJoinOnCollectionOfEmbeddedWithTwoEmbeddedCollections() {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform(
" SELECT d.email " +
" FROM org.infinispan.query.dsl.embedded.impl.model.Employee e " +
" JOIN e.contactDetails d " +
" JOIN e.alternativeContactDetails a" +
" WHERE d.address.postCode='EA123' AND a.email='ninja647@mailinator.com'");
assertThat(result.getQuery().toString()).isEqualTo("+contactDetails.address.postCode:EA123 +alternativeContactDetails.email:ninja647@mailinator.com");
assertThat(result.getProjections()).containsOnly("contactDetails.email");
}
private void assertGeneratedLuceneQuery(String queryString, String expectedLuceneQuery) {
assertGeneratedLuceneQuery(queryString, null, expectedLuceneQuery);
}
private void assertGeneratedLuceneQuery(String queryString, Map<String, Object> namedParameters, String expectedLuceneQuery) {
LuceneQueryParsingResult<Class<?>> result = parseAndTransform(queryString, namedParameters);
assertThat(result.getQuery().toString()).isEqualTo(expectedLuceneQuery);
}
private LuceneQueryParsingResult<Class<?>> parseAndTransform(String queryString) {
return parseAndTransform(queryString, null);
}
private LuceneQueryParsingResult<Class<?>> parseAndTransform(String queryString, Map<String, Object> namedParameters) {
ExtendedSearchIntegrator searchFactory = factoryHolder.getSearchFactory();
HibernateSearchPropertyHelper propertyHelper = new HibernateSearchPropertyHelper(searchFactory, new ReflectionEntityNamesResolver(null));
IckleParsingResult<Class<?>> ickleParsingResult = IckleParser.parse(queryString, propertyHelper);
LuceneQueryMaker<Class<?>> luceneQueryMaker = new LuceneQueryMaker<>(searchFactory, propertyHelper.getDefaultFieldBridgeProvider());
return luceneQueryMaker.transform(ickleParsingResult, namedParameters, ickleParsingResult.getTargetEntityMetadata());
}
}