SOLR-11136: Fix solrj XMLResponseParser when nested docs transformer is used with indented XML

This commit is contained in:
Chris Hostetter 2017-07-21 17:25:51 -07:00
parent 8821882400
commit eae2efcbd9
3 changed files with 57 additions and 17 deletions

View File

@ -378,6 +378,8 @@ Bug Fixes
* SOLR-11057: Fix overflow in point range queries when querying the type limits
(e.g. q=field_i:{Integer.MAX_VALUE TO Integer.MAX_VALUE]) (Tomás Fernández Löbbe)
* SOLR-11136: Fix solrj XMLResponseParser when nested docs transformer is used with indented XML (hossman)
Optimizations
----------------------

View File

@ -404,6 +404,14 @@ public class XMLResponseParser extends ResponseParser
throw new RuntimeException( "this must be known type! not: "+parser.getLocalName() );
}
if ( type == KnownType.DOC) {
doc.addChildDocument(readDocument(parser));
depth--; // (nested) readDocument clears out the (nested) 'endElement'
continue; // may be more child docs, or other fields
}
// other then nested documents, all other possible nested elements require a name...
name = null;
int cnt = parser.getAttributeCount();
for( int i=0; i<cnt; i++ ) {
@ -412,15 +420,6 @@ public class XMLResponseParser extends ResponseParser
break;
}
}
//Nested documents
while( type == KnownType.DOC) {
doc.addChildDocument(readDocument(parser));
int event = parser.next();
if (event == XMLStreamConstants.END_ELEMENT) { //Doc ends
return doc;
}
}
if( name == null ) {
throw new XMLStreamException( "requires 'name' attribute: "+parser.getLocalName(), parser.getLocation() );

View File

@ -1764,7 +1764,7 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
SolrClient client = getSolrClient();
client.deleteByQuery("*:*");
client.commit();
int numRootDocs = TestUtil.nextInt(random(), 10, 100);
int maxDepth = TestUtil.nextInt(random(), 2, 5);
@ -1777,14 +1777,14 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
client.commit();
// sanity check
SolrQuery q = new SolrQuery("*:*");
SolrQuery q = new SolrQuery("q", "*:*", "indent", "true");
QueryResponse resp = client.query(q);
assertEquals("Doc count does not match",
allDocs.size(), resp.getResults().getNumFound());
// base check - we know there is an exact number of these root docs
q = new SolrQuery("level_i:0");
q = new SolrQuery("q","level_i:0", "indent", "true");
q.setFields("*", "[child parentFilter=\"level_i:0\"]");
resp = client.query(q);
assertEquals("topLevel count does not match", numRootDocs,
@ -1793,6 +1793,7 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
String docId = (String)outDoc.getFieldValue("id");
SolrInputDocument origDoc = allDocs.get(docId);
assertNotNull("docId not found: " + docId, origDoc);
assertEquals("name mismatch", origDoc.getFieldValue("name"), outDoc.getFieldValue("name"));
assertEquals("kids mismatch",
origDoc.hasChildDocuments(), outDoc.hasChildDocuments());
if (outDoc.hasChildDocuments()) {
@ -1813,16 +1814,17 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
String childFilter = "level_i:" + kidLevel;
int maxKidCount = TestUtil.nextInt(random(), 1, 37);
q = new SolrQuery("*:*");
q = new SolrQuery("q", "*:*", "indent", "true");
q.setFilterQueries(parentFilter);
q.setFields("id,[child parentFilter=\"" + parentFilter +
"\" childFilter=\"" + childFilter +
"\" limit=\"" + maxKidCount + "\"]");
"\" limit=\"" + maxKidCount + "\"], name");
resp = client.query(q);
for (SolrDocument outDoc : resp.getResults()) {
String docId = (String)outDoc.getFieldValue("id");
SolrInputDocument origDoc = allDocs.get(docId);
assertNotNull("docId not found: " + docId, origDoc);
assertEquals("name mismatch", origDoc.getFieldValue("name"), outDoc.getFieldValue("name"));
assertEquals("kids mismatch",
origDoc.hasChildDocuments(), outDoc.hasChildDocuments());
if (outDoc.hasChildDocuments()) {
@ -1845,6 +1847,42 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
}
}
}
// bespoke check - use child transformer twice in one query to get diff kids, with name field in between
{
q = new SolrQuery("q","level_i:0", "indent", "true");
// NOTE: should be impossible to have more then 7 direct kids, or more then 49 grandkids
q.setFields("id", "[child parentFilter=\"level_i:0\" limit=100 childFilter=\"level_i:1\"]",
"name", "[child parentFilter=\"level_i:0\" limit=100 childFilter=\"level_i:2\"]");
resp = client.query(q);
assertEquals("topLevel count does not match", numRootDocs,
resp.getResults().getNumFound());
for (SolrDocument outDoc : resp.getResults()) {
String docId = (String)outDoc.getFieldValue("id");
SolrInputDocument origDoc = allDocs.get(docId);
assertNotNull("docId not found: " + docId, origDoc);
assertEquals("name mismatch", origDoc.getFieldValue("name"), outDoc.getFieldValue("name"));
assertEquals("kids mismatch",
origDoc.hasChildDocuments(), outDoc.hasChildDocuments());
if (outDoc.hasChildDocuments()) {
for (SolrDocument kid : outDoc.getChildDocuments()) {
String kidId = (String)kid.getFieldValue("id");
SolrInputDocument origChild = findDecendent(origDoc, kidId);
assertNotNull(docId + " doesn't have decendent " + kidId,
origChild);
}
// the total number of kids should be our direct kids and our grandkids
int expectedKidsOut = origDoc.getChildDocuments().size();
for (SolrInputDocument origKid : origDoc.getChildDocuments()) {
if (origKid.hasChildDocuments()) {
expectedKidsOut += origKid.getChildDocuments().size();
}
}
assertEquals("total number of kids and grandkids doesn't match expected",
expectedKidsOut, outDoc.getChildDocuments().size());
}
}
}
// fully randomized
// verifications are driven only by the results
@ -1857,20 +1895,21 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
String childFilter = "level_i:[" + kidLevelMin + " TO " + kidLevelMax + "]";
int maxKidCount = TestUtil.nextInt(random(), 1, 7);
q = new SolrQuery("*:*");
q = new SolrQuery("q","*:*", "indent", "true");
if (random().nextBoolean()) {
String name = names[TestUtil.nextInt(random(), 0, names.length-1)];
q = new SolrQuery("name:" + name);
q = new SolrQuery("q", "name:" + name, "indent", "true");
}
q.setFilterQueries(parentFilter);
q.setFields("id,[child parentFilter=\"" + parentFilter +
"\" childFilter=\"" + childFilter +
"\" limit=\"" + maxKidCount + "\"]");
"\" limit=\"" + maxKidCount + "\"],name");
resp = client.query(q);
for (SolrDocument outDoc : resp.getResults()) {
String docId = (String)outDoc.getFieldValue("id");
SolrInputDocument origDoc = allDocs.get(docId);
assertNotNull("docId not found: " + docId, origDoc);
assertEquals("name mismatch", origDoc.getFieldValue("name"), outDoc.getFieldValue("name"));
// we can't always assert origHasKids==outHasKids, original kids
// might not go deep enough for childFilter...
if (outDoc.hasChildDocuments()) {