Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[13.0.x] ISPN-13499 Ickle fulltext query not working with query parameters #10026

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,25 +1,24 @@
package org.infinispan.objectfilter.impl.syntax;

import java.util.Map;

/**
* @author anistor@redhat.com
* @since 9.0
*/
public final class FullTextTermExpr implements PrimaryPredicateExpr {

private final ValueExpr leftChild;

private final String term;

private final Integer fuzzySlop;
private final ConstantValueExpr.ParamPlaceholder paramPlaceholder;

public FullTextTermExpr(ValueExpr leftChild, String term, Integer fuzzySlop) {
public FullTextTermExpr(ValueExpr leftChild, Object comparisonObject, Integer fuzzySlop) {
this.leftChild = leftChild;
this.term = term;
this.term = comparisonObject.toString();
this.fuzzySlop = fuzzySlop;
}

public String getTerm() {
return term;
this.paramPlaceholder = (comparisonObject instanceof ConstantValueExpr.ParamPlaceholder) ?
(ConstantValueExpr.ParamPlaceholder) comparisonObject : null;
}

public Integer getFuzzySlop() {
Expand All @@ -45,4 +44,25 @@ public String toString() {
public String toQueryString() {
return leftChild.toQueryString() + ":'" + term + "'" + (fuzzySlop != null ? "~" + fuzzySlop : "");
}

public String getTerm(Map<String, Object> namedParameters) {
if (paramPlaceholder == null) {
return term;
}

String paramName = paramPlaceholder.getName();
if (namedParameters == null) {
throw new IllegalStateException("Missing value for parameter " + paramName);
}

Comparable value = (Comparable) namedParameters.get(paramName);
if (value == null) {
throw new IllegalStateException("Missing value for parameter " + paramName);
}
if (value instanceof String) {
return (String) value;
}

throw new IllegalStateException("Parameter must be a string " + paramName);
}
}
Expand Up @@ -59,8 +59,8 @@ public void setEntityType(TypeMetadata entityType) {
stack.push(new LazyRootBooleanExpr());
}

public void addFullTextTerm(PropertyPath<?> propertyPath, String value, Integer fuzzySlop) {
push(new FullTextTermExpr(makePropertyValueExpr(propertyPath), value, fuzzySlop));
public void addFullTextTerm(PropertyPath<?> propertyPath, Object comparisonObject, Integer fuzzySlop) {
push(new FullTextTermExpr(makePropertyValueExpr(propertyPath), comparisonObject, fuzzySlop));
}

public void addFullTextRegexp(PropertyPath<?> propertyPath, String regexp) {
Expand Down
Expand Up @@ -368,7 +368,7 @@ public void predicateFullTextTerm(String term, String fuzzyFlop) {
if (phase == Phase.WHERE) {
checkAnalyzed(property, true);
Object comparisonObject = parameterValue(term);
whereBuilder.addFullTextTerm(property, comparisonObject.toString(), fuzzyFlop == null ? null : (fuzzyFlop.equals("~") ? 2 : Integer.parseInt(fuzzyFlop)));
whereBuilder.addFullTextTerm(property, comparisonObject, fuzzyFlop == null ? null : (fuzzyFlop.equals("~") ? 2 : Integer.parseInt(fuzzyFlop)));
} else if (phase == Phase.HAVING) {
throw log.getFullTextQueriesNotAllowedInHavingClauseException();
} else {
Expand Down
Expand Up @@ -282,7 +282,7 @@ private Analyzer getAnalyzer(PropertyPath<?> propertyPath) {
@Override
public PredicateFinalStep visit(FullTextTermExpr fullTextTermExpr) {
PropertyValueExpr propertyValueExpr = (PropertyValueExpr) fullTextTermExpr.getChild();
String text = fullTextTermExpr.getTerm();
String text = fullTextTermExpr.getTerm(namedParameters);
String absoluteFieldPath = propertyValueExpr.getPropertyPath().asStringPath();

int asteriskPos = text.indexOf(LUCENE_MULTIPLE_CHARACTERS_WILDCARD);
Expand Down
31 changes: 31 additions & 0 deletions query/src/test/java/org/infinispan/query/model/Book.java
@@ -0,0 +1,31 @@
package org.infinispan.query.model;

import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;

@Indexed
public class Book {

@GenericField
private String title;

@FullTextField
private String description;

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}
@@ -0,0 +1,58 @@
package org.infinispan.query.parameter;

import static org.assertj.core.api.Assertions.assertThat;
import static org.infinispan.configuration.cache.IndexStorage.LOCAL_HEAP;

import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.query.Search;
import org.infinispan.query.dsl.Query;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.dsl.QueryResult;
import org.infinispan.query.model.Book;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

@Test(groups = "functional", testName = "query.parameter.FullTextParameterTest")
public class FullTextParameterTest extends SingleCacheManagerTest {

@Override
protected EmbeddedCacheManager createCacheManager() throws Exception {
ConfigurationBuilder builder = getDefaultStandaloneCacheConfig(false);
builder.indexing().enable()
.storage(LOCAL_HEAP)
.addIndexedEntity(Book.class);

return TestCacheManagerFactory.createCacheManager(builder);
}

@BeforeMethod(alwaysRun = true)
public void beforeMethod() {
Book book = new Book();
book.setTitle("island");
book.setDescription("A place surrounded by the sea.");
cache.put(1, book);
}

public void fulltext() {
QueryFactory factory = Search.getQueryFactory(cache);
Query<Book> query = factory.create("from org.infinispan.query.model.Book where description : :description");
query.setParameter("description", "place");
QueryResult<Book> result = query.execute();

assertThat(result.hitCount()).hasValue(1L);
assertThat(result.list()).extracting("title").contains("island");
}

public void generic() {
QueryFactory factory = Search.getQueryFactory(cache);
Query<Book> query = factory.create("from org.infinispan.query.model.Book where title = :title");
query.setParameter("title", "island");
QueryResult<Book> result = query.execute();

assertThat(result.hitCount()).hasValue(1L);
assertThat(result.list()).extracting("title").contains("island");
}
}