SOLR-10404: fetch() streaming expression: escape values in generated query.

This commit is contained in:
David Smiley 2017-04-05 08:56:50 -04:00
parent 50ed729459
commit cb9f151db4
3 changed files with 27 additions and 14 deletions

View File

@ -213,6 +213,9 @@ Bug Fixes
* SOLR-10421: Fix params persistence for solr/contrib/ltr (MinMax|Standard)Normalizer classes. * SOLR-10421: Fix params persistence for solr/contrib/ltr (MinMax|Standard)Normalizer classes.
(Jianxiong Dong, Christine Poerschke) (Jianxiong Dong, Christine Poerschke)
* SOLR-10404: The fetch() streaming expression wouldn't work if a value included query syntax chars (like :+-).
Fixed, and enhanced the generated query to not pollute the queryCache. (David Smiley)
================== 6.5.0 ================== ================== 6.5.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

View File

@ -35,6 +35,7 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter; import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue; import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ModifiableSolrParams;
import static org.apache.solr.common.params.CommonParams.SORT; import static org.apache.solr.common.params.CommonParams.SORT;
@ -208,9 +209,8 @@ public class FetchStream extends TupleStream implements Expressible {
} }
private void fetchBatch() throws IOException { private void fetchBatch() throws IOException {
Tuple EOFTuple = null; Tuple EOFTuple = null;
List<Tuple> batch = new ArrayList(); List<Tuple> batch = new ArrayList<>(batchSize);
for(int i=0; i<batchSize; i++) { for(int i=0; i<batchSize; i++) {
Tuple tuple = stream.read(); Tuple tuple = stream.read();
if(tuple.EOF) { if(tuple.EOF) {
@ -222,18 +222,12 @@ public class FetchStream extends TupleStream implements Expressible {
} }
if(batch.size() > 0) { if(batch.size() > 0) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder(batch.size() * 10 + 20);
buf.append(rightKey); buf.append("{! df=").append(rightKey).append(" q.op=OR cache=false }");//disable queryCache
buf.append(":("); for (Tuple tuple : batch) {
for (int i = 0; i < batch.size(); i++) {
if (i > 0) {
buf.append(" ");
}
Tuple tuple = batch.get(i);
String key = tuple.getString(leftKey); String key = tuple.getString(leftKey);
buf.append(key); buf.append(' ').append(ClientUtils.escapeQueryChars(key));
} }
buf.append(")");
ModifiableSolrParams params = new ModifiableSolrParams(); ModifiableSolrParams params = new ModifiableSolrParams();
params.add("q", buf.toString()); params.add("q", buf.toString());
@ -245,7 +239,7 @@ public class FetchStream extends TupleStream implements Expressible {
StreamContext newContext = new StreamContext(); StreamContext newContext = new StreamContext();
newContext.setSolrClientCache(streamContext.getSolrClientCache()); newContext.setSolrClientCache(streamContext.getSolrClientCache());
cloudSolrStream.setStreamContext(newContext); cloudSolrStream.setStreamContext(newContext);
Map<String, Tuple> fetched = new HashMap(); Map<String, Tuple> fetched = new HashMap<>();
try { try {
cloudSolrStream.open(); cloudSolrStream.open();
while (true) { while (true) {

View File

@ -1044,7 +1044,7 @@ public class StreamExpressionTest extends SolrCloudTestCase {
@Test @Test
public void testFetchStream() throws Exception { public void testFetchStream() throws Exception {
SolrClientCache solrClientCache = new SolrClientCache(); SolrClientCache solrClientCache = new SolrClientCache();//TODO share in @Before ; close in @After ?
new UpdateRequest() new UpdateRequest()
.add(id, "0", "a_s", "hello0", "a_i", "0", "a_f", "1", "subject", "blah blah blah 0") .add(id, "0", "a_s", "hello0", "a_i", "0", "a_f", "1", "subject", "blah blah blah 0")
@ -1123,6 +1123,22 @@ public class StreamExpressionTest extends SolrCloudTestCase {
assertTrue("blah blah blah 8".equals(t.getString("subject"))); assertTrue("blah blah blah 8".equals(t.getString("subject")));
t = tuples.get(9); t = tuples.get(9);
assertTrue("blah blah blah 9".equals(t.getString("subject"))); assertTrue("blah blah blah 9".equals(t.getString("subject")));
// SOLR-10404 test that "hello 99" as a value gets escaped
new UpdateRequest()
.add(id, "99", "a1_s", "hello 99", "a2_s", "hello 99", "subject", "blah blah blah 99")
.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
stream = factory.constructStream("fetch("+ COLLECTIONORALIAS +", search(" + COLLECTIONORALIAS + ", q=" + id + ":99, fl=\"id,a1_s\", sort=\"id asc\"), on=\"a1_s=a2_s\", fl=\"subject\")");
context = new StreamContext();
context.setSolrClientCache(solrClientCache);
stream.setStreamContext(context);
tuples = getTuples(stream);
assertEquals(1, tuples.size());
t = tuples.get(0);
assertTrue("blah blah blah 99".equals(t.getString("subject")));
solrClientCache.close(); solrClientCache.close();
} }