GEODE-2943: Wildcard and space queries are now handled correctly
Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/db028ac0 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/db028ac0 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/db028ac0 Branch: refs/heads/feature/GEODE-2632-17 Commit: db028ac063a5701ea8122225ae58acbce269f1aa Parents: 3cbb6fc Author: Barry Oglesby <bogle...@pivotal.io> Authored: Fri May 19 15:24:35 2017 -0700 Committer: Barry Oglesby <bogle...@pivotal.io> Committed: Tue May 23 11:16:35 2017 -0700 ---------------------------------------------------------------------- .../geode/internal/i18n/LocalizedStrings.java | 2 ++ .../lucene/internal/StringQueryProvider.java | 8 +++-- .../cache/lucene/LuceneQueriesAccessorBase.java | 19 ++++++++++ .../cache/lucene/LuceneQueriesDUnitTest.java | 37 ++++++++++++++++++++ .../cli/LuceneIndexCommandsDUnitTest.java | 25 ------------- 5 files changed, 64 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/db028ac0/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java b/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java index 2fb8c8d..f19c4e7 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java +++ b/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java @@ -7692,6 +7692,8 @@ public class LocalizedStrings { new StringId(6657, "Lucene index {0} on region {1} already exists."); public static final StringId LuceneIndexCreation_IGNORING_DUPLICATE_INDEX_CREATION_0_ON_REGION_1 = new StringId(6658, "Ignoring duplicate index creation for Lucene index {0} on region {1}"); + public static final StringId StringQueryProvider_PARSING_QUERY_0_FAILED_DUE_TO_1 = + new StringId(6659, "Parsing query {0} failed due to: {1}"); /** Testing strings, messageId 90000-99999 **/ http://git-wip-us.apache.org/repos/asf/geode/blob/db028ac0/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/StringQueryProvider.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/StringQueryProvider.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/StringQueryProvider.java index 7b72748..82dd10f 100644 --- a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/StringQueryProvider.java +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/StringQueryProvider.java @@ -19,6 +19,7 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.logging.log4j.Logger; import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser; @@ -69,14 +70,17 @@ public class StringQueryProvider implements LuceneQueryProvider, DataSerializabl String[] fields = index.getFieldNames(); LuceneIndexImpl indexImpl = (LuceneIndexImpl) index; StandardQueryParser parser = new StandardQueryParser(indexImpl.getAnalyzer()); + parser.setAllowLeadingWildcard(true); try { luceneQuery = parser.parse(query, defaultField); if (logger.isDebugEnabled()) { logger.debug("User query " + query + " is parsed to be: " + luceneQuery); } } catch (QueryNodeException e) { - logger.debug("Query node exception:" + query, e); - throw new LuceneQueryException("Malformed lucene query: " + query, e); + logger.warn("Caught the following exception attempting parse query '" + query + "': ", e); + throw new LuceneQueryException( + LocalizedStrings.StringQueryProvider_PARSING_QUERY_0_FAILED_DUE_TO_1 + .toLocalizedString("'" + query + "'", e.getMessage())); } } return luceneQuery; http://git-wip-us.apache.org/repos/asf/geode/blob/db028ac0/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesAccessorBase.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesAccessorBase.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesAccessorBase.java index 9568ab8..86993da 100644 --- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesAccessorBase.java +++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesAccessorBase.java @@ -22,6 +22,7 @@ import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.REGION_NAME import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.apache.geode.cache.Cache; import org.apache.geode.cache.Region; @@ -106,6 +107,24 @@ public class LuceneQueriesAccessorBase extends LuceneDUnitTest { }); } + protected void executeTextSearchWithExpectedException(VM vm, String queryString, + String defaultField, Class expctedExceptionClass) { + vm.invoke(() -> { + Cache cache = getCache(); + + LuceneService service = LuceneServiceProvider.get(cache); + LuceneQuery<Integer, TestObject> query; + query = service.createLuceneQueryFactory().setLimit(1000).setPageSize(1000).create(INDEX_NAME, + REGION_NAME, queryString, defaultField); + try { + Collection<?> results = query.findKeys(); + fail("Query " + defaultField + ":" + queryString + " should not have succeeded"); + } catch (Exception e) { + assertEquals(expctedExceptionClass, e.getClass()); + } + }); + } + protected void addCallbackToTriggerRebalance(VM vm) { vm.invoke(() -> { IndexRepositorySpy spy = IndexRepositorySpy.injectSpy(); http://git-wip-us.apache.org/repos/asf/geode/blob/db028ac0/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java index c319a16..ba71010 100644 --- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java +++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java @@ -169,6 +169,43 @@ public class LuceneQueriesDUnitTest extends LuceneQueriesAccessorBase { executeTextSearch(accessor, "world", "noEntriesMapped", 0); } + @Test + @Parameters(method = "getListOfRegionTestTypes") + public void verifyWildcardQueriesSucceed(RegionTestableType regionTestType) { + SerializableRunnableIF createIndex = () -> { + LuceneService luceneService = LuceneServiceProvider.get(getCache()); + luceneService.createIndexFactory().addField("text").create(INDEX_NAME, REGION_NAME); + }; + dataStore1.invoke(() -> initDataStore(createIndex, regionTestType)); + dataStore2.invoke(() -> initDataStore(createIndex, regionTestType)); + accessor.invoke(() -> initAccessor(createIndex, regionTestType)); + putDataInRegion(accessor); + assertTrue(waitForFlushBeforeExecuteTextSearch(accessor, 60000)); + assertTrue(waitForFlushBeforeExecuteTextSearch(dataStore1, 60000)); + executeTextSearch(accessor, "*", "*", 3); + executeTextSearch(accessor, "*:*", "text", 3); + executeTextSearch(accessor, "*:*", "XXX", 3); + executeTextSearch(accessor, "*", "text", 3); + } + + @Test + @Parameters(method = "getListOfRegionTestTypes") + public void verifySpaceQueriesFail(RegionTestableType regionTestType) { + SerializableRunnableIF createIndex = () -> { + LuceneService luceneService = LuceneServiceProvider.get(getCache()); + luceneService.createIndexFactory().addField("text").create(INDEX_NAME, REGION_NAME); + }; + dataStore1.invoke(() -> initDataStore(createIndex, regionTestType)); + dataStore2.invoke(() -> initDataStore(createIndex, regionTestType)); + accessor.invoke(() -> initAccessor(createIndex, regionTestType)); + putDataInRegion(accessor); + assertTrue(waitForFlushBeforeExecuteTextSearch(accessor, 60000)); + assertTrue(waitForFlushBeforeExecuteTextSearch(dataStore1, 60000)); + executeTextSearchWithExpectedException(accessor, " ", "*", LuceneQueryException.class); + executeTextSearchWithExpectedException(accessor, " ", "text", LuceneQueryException.class); + executeTextSearchWithExpectedException(accessor, " ", "XXX", LuceneQueryException.class); + } + protected void putDataInRegion(VM vm) { vm.invoke(() -> { final Cache cache = getCache(); http://git-wip-us.apache.org/repos/asf/geode/blob/db028ac0/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java index c96f846..bc4c68e 100755 --- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java +++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java @@ -433,31 +433,6 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase { } @Test - public void searchWithInvalidQueryStringShouldReturnError() throws Exception { - final VM vm1 = Host.getHost(0).getVM(1); - - createIndex(vm1); - Map<String, TestObject> entries = new HashMap<>(); - entries.put("A", new TestObject("value1 ", "value2", "value3")); - entries.put("B", new TestObject("ABC", "EFG", "HIJ"));; - putEntries(vm1, entries, 2); - - CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_SEARCH_INDEX); - csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME, INDEX_NAME); - csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, REGION_NAME); - csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING, "WF~*"); - csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD, "field2"); - - String commandString = csb.toString(); - writeToLog("Command String :\n ", commandString); - CommandResult commandResult = executeCommand(commandString); - String resultAsString = commandResultToString(commandResult); - writeToLog("Result String :\n ", resultAsString); - assertEquals(Status.ERROR, commandResult.getStatus()); - assertTrue(resultAsString.contains("Leading wildcard is not allowed: field2:*")); - } - - @Test public void searchOnIndexWithoutRegionShouldReturnError() throws Exception { final VM vm1 = Host.getHost(0).getVM(1);