SOLR-12683: HashQuery will throw an exception if more than 4 partitionKeys is specified. Earlier after the 4th partitionKey the keys would be silently ignored.

This commit is contained in:
Varun Thacker 2018-08-20 15:21:19 -07:00
parent 66d500b5a5
commit 5eab1c3c68
3 changed files with 44 additions and 9 deletions

View File

@ -251,6 +251,9 @@ Bug Fixes
* SOLR-12598: Do not fetch non-stored fields (Nikolay Khitrin, Erick Erickson) * SOLR-12598: Do not fetch non-stored fields (Nikolay Khitrin, Erick Erickson)
* SOLR-12683: HashQuery will throw an exception if more than 4 partitionKeys is specified.
Earlier after the 4th partitionKey the keys would be silently ignored. (Varun Thacker)
Optimizations Optimizations
---------------------- ----------------------

View File

@ -73,15 +73,18 @@ public class HashQParserPlugin extends QParserPlugin {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "workers needs to be more than 1"); throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "workers needs to be more than 1");
} }
int worker = localParams.getInt("worker", 0); int worker = localParams.getInt("worker", 0);
String keys = params.get("partitionKeys"); String keyParam = params.get("partitionKeys");
keys = keys.replace(" ", ""); String[] keys = keyParam.replace(" ", "").split(",");
if (keys.length > 4) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "HashQuery supports upto 4 partitionKeys");
}
return new HashQuery(keys, workers, worker); return new HashQuery(keys, workers, worker);
} }
} }
private static class HashQuery extends ExtendedQueryBase implements PostFilter { private static class HashQuery extends ExtendedQueryBase implements PostFilter {
private String keysParam; private String[] keys;
private int workers; private int workers;
private int worker; private int worker;
@ -95,7 +98,7 @@ public class HashQParserPlugin extends QParserPlugin {
public int hashCode() { public int hashCode() {
return classHash() + return classHash() +
31 * keysParam.hashCode() + 31 * keys.hashCode() +
31 * workers + 31 * workers +
31 * worker; 31 * worker;
} }
@ -106,13 +109,13 @@ public class HashQParserPlugin extends QParserPlugin {
} }
private boolean equalsTo(HashQuery other) { private boolean equalsTo(HashQuery other) {
return keysParam.equals(other.keysParam) && return keys.equals(other.keys) &&
workers == other.workers && workers == other.workers &&
worker == other.worker; worker == other.worker;
} }
public HashQuery(String keysParam, int workers, int worker) { public HashQuery(String[] keys, int workers, int worker) {
this.keysParam = keysParam; this.keys = keys;
this.workers = workers; this.workers = workers;
this.worker = worker; this.worker = worker;
} }
@ -120,7 +123,6 @@ public class HashQParserPlugin extends QParserPlugin {
@Override @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException { public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
String[] keys = keysParam.split(",");
SolrIndexSearcher solrIndexSearcher = (SolrIndexSearcher)searcher; SolrIndexSearcher solrIndexSearcher = (SolrIndexSearcher)searcher;
IndexReaderContext context = solrIndexSearcher.getTopReaderContext(); IndexReaderContext context = solrIndexSearcher.getTopReaderContext();
@ -224,7 +226,6 @@ public class HashQParserPlugin extends QParserPlugin {
} }
public DelegatingCollector getFilterCollector(IndexSearcher indexSearcher) { public DelegatingCollector getFilterCollector(IndexSearcher indexSearcher) {
String[] keys = keysParam.split(",");
HashKey[] hashKeys = new HashKey[keys.length]; HashKey[] hashKeys = new HashKey[keys.length];
SolrIndexSearcher searcher = (SolrIndexSearcher)indexSearcher; SolrIndexSearcher searcher = (SolrIndexSearcher)indexSearcher;
IndexSchema schema = searcher.getSchema(); IndexSchema schema = searcher.getSchema();

View File

@ -18,6 +18,7 @@ package org.apache.solr.search;
import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ModifiableSolrParams;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -54,6 +55,36 @@ public class TestHashQParserPlugin extends SolrTestCaseJ4 {
} }
} }
@Test
public void testManyHashPartitions() throws Exception {
ModifiableSolrParams params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!hash worker=0 workers=2 cost="+getCost(random())+"}");
params.add("partitionKeys", "a_i,a_s,a_i,a_s");
params.add("wt", "xml");
String response = h.query(req(params));
h.validateXPath(response, "//*[@numFound='0']");
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!hash worker=0 workers=2 cost="+getCost(random())+"}");
params.add("partitionKeys", "a_i,a_s,a_i,a_s,a_i");
params.add("wt", "xml");
ModifiableSolrParams finalParams = params;
expectThrows(SolrException.class, () -> h.query(req(finalParams)));
}
@Test
public void testLessWorkers() {
ModifiableSolrParams params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!hash worker=0 workers=1 cost="+getCost(random())+"}");
params.add("partitionKeys", "a_i");
params.add("wt", "xml");
ModifiableSolrParams finalParams = params;
expectThrows(SolrException.class, () -> h.query(req(finalParams)));
}
@Test @Test
public void testHashPartitionWithEmptyValues() throws Exception { public void testHashPartitionWithEmptyValues() throws Exception {