SOLR-13255 : ClasscastException when URPs try to read a String field which returns a ByteArrayUTF8CHarSequence . This is a regression in release 7.7

This commit is contained in:
Noble Paul 2019-02-20 22:19:18 +11:00
parent 3ef6e015dd
commit a89b065c1f
6 changed files with 93 additions and 11 deletions

View File

@ -247,6 +247,10 @@ Bug Fixes
this issue reverts the default replica placement policy to the 'legacy' assignment policy that was the default until
Solr 7.4. (Gus Heck, Andrzej Bialecki, Bram Van Dam, shalin)
* SOLR-13255 : ClasscastException when URPs try to read a String field which returns a ByteArrayUTF8CHarSequence . This is a regression
in release 7.7 (noble)
Improvements
----------------------

View File

@ -17,16 +17,19 @@
package org.apache.solr.update.processor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.ByteArrayUtf8CharSequence;
import org.apache.solr.core.SolrCore;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.servlet.SolrRequestParsers;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.servlet.SolrRequestParsers;
public abstract class LanguageIdentifierUpdateProcessorFactoryTestCase extends SolrTestCaseJ4 {
@ -383,6 +386,25 @@ public abstract class LanguageIdentifierUpdateProcessorFactoryTestCase extends S
*/
private SolrInputDocument process(SolrInputDocument origDoc) {
SolrInputDocument modifiedDoc = origDoc.deepCopy();
if (random().nextBoolean()) {
modifiedDoc.forEach((s, f) -> {
Object rawVal = f.getRawValue();
if (rawVal instanceof Collection) {
Collection rawValue = (Collection) rawVal;
ArrayList<Object> newVal = new ArrayList<>(rawValue.size());
for (Object o : rawValue) {
if (o instanceof String) {
newVal.add(new ByteArrayUtf8CharSequence((String) o));
} else {
newVal.add(rawVal);
}
}
f.setValue(newVal);
} else if (rawVal instanceof String) {
f.setValue(new ByteArrayUtf8CharSequence((String) rawVal));
}
});
}
liProcessor.process(modifiedDoc);
return modifiedDoc;
}

View File

@ -135,7 +135,7 @@ public class DocumentBuilder {
// Load fields from SolrDocument to Document
for( SolrInputField field : doc ) {
if (field.getFirstValue() instanceof SolrDocumentBase) {
if (field.getFirstRawValue() instanceof SolrDocumentBase) {
if (ignoreNestedDocs) {
continue;
}
@ -159,7 +159,9 @@ public class DocumentBuilder {
// load each field value
boolean hasField = false;
try {
for( Object v : field ) {
Iterator it = field.getRawIterator();
while (it.hasNext()) {
Object v = it.next();
if( v == null ) {
continue;
}

View File

@ -21,6 +21,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import static org.apache.solr.common.util.ByteArrayUtf8CharSequence.convertCharSeq;
/**
*
* @since solr 1.3
@ -111,11 +113,11 @@ public class SolrInputField implements Iterable<Object>, Serializable
if( value instanceof Collection ) {
Collection c = (Collection<Object>)value;
if( c.size() > 0 ) {
return c.iterator().next();
return convertCharSeq(c.iterator().next());
}
return null;
}
return value;
return convertCharSeq(value);
}
/**
@ -123,6 +125,28 @@ public class SolrInputField implements Iterable<Object>, Serializable
* will be a collection.
*/
public Object getValue() {
return convertCharSeq(value);
}
/**
* Return a value as is without converting and CharSequence Objects
*/
public Object getRawValue() {
return value;
}
/**
* Return the first value as is without converting and CharSequence Objects
*/
public Object getFirstRawValue() {
if (value instanceof Collection) {
Collection c = (Collection<Object>) value;
if (c.size() > 0) {
return c.iterator().next();
}
return null;
}
return value;
}
@ -132,12 +156,12 @@ public class SolrInputField implements Iterable<Object>, Serializable
*/
@SuppressWarnings("unchecked")
public Collection<Object> getValues() {
if( value instanceof Collection ) {
return (Collection<Object>)value;
if (value instanceof Collection) {
return convertCharSeq((Collection<Object>) value);
}
if( value != null ) {
Collection<Object> vals = new ArrayList<>(1);
vals.add( value );
vals.add(convertCharSeq(value));
return vals;
}
return null;
@ -165,8 +189,33 @@ public class SolrInputField implements Iterable<Object>, Serializable
}
@Override
public Iterator<Object> iterator(){
if( value instanceof Collection ) {
return (convertCharSeq ((Collection)value)).iterator();
}
return new Iterator<Object>() {
boolean nxt = (value!=null);
@Override
public boolean hasNext() {
return nxt;
}
@Override
public Object next() {
nxt = false;
return convertCharSeq(value);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@SuppressWarnings("unchecked")
public Iterator<Object> iterator() {
public Iterator<Object> getRawIterator() {
if( value instanceof Collection ) {
return ((Collection)value).iterator();
}

View File

@ -73,6 +73,10 @@ public class ByteArrayUtf8CharSequence implements Utf8CharSequence {
return buf[offset + idx];
}
/**
* this is for internal use to get a cached string value.
* returns null if There is no cached String value
*/
public String getStringOrNull() {
return utf16;
}
@ -209,6 +213,7 @@ public class ByteArrayUtf8CharSequence implements Utf8CharSequence {
public static Object convertCharSeq(Object o) {
if (o == null) return null;
if (o instanceof Utf8CharSequence) return ((Utf8CharSequence) o).toString();
if (o instanceof Collection) return convertCharSeq((Collection) o);
return o;
}

View File

@ -357,7 +357,7 @@ public class JavaBinCodec implements PushWriter {
return true;
}
if (val instanceof SolrInputField) {
return writeKnownType(((SolrInputField) val).getValue());
return writeKnownType(((SolrInputField) val).getRawValue());
}
if (val instanceof IteratorWriter) {
writeIterator((IteratorWriter) val);