SOLR-2339: Fix sorting to explicitly generate an error if you attempt to sort on a multiValued field.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1067030 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2011-02-03 23:21:44 +00:00
parent 69ad01cb98
commit dc16b7efea
26 changed files with 271 additions and 161 deletions

View File

@ -53,6 +53,15 @@ Upgrading from Solr 3.1-dev
legacy behavior should set a default value for the 'mm' param in legacy behavior should set a default value for the 'mm' param in
their solrconfig.xml file. their solrconfig.xml file.
* In previous releases, sorting on fields that are "multiValued"
(either by explicit declaration in schema.xml or by implict behavior
because the "version" attribute on the schema was less then 1.2) did
not generally work, but it would sometimes silently act as if it
succeeded and order the docs arbitrarily. Solr will now fail on any
attempt to sort on a multivalued field
Detailed Change List Detailed Change List
---------------------- ----------------------
@ -170,6 +179,8 @@ Bug Fixes
* SOLR-1940: Fix SolrDispatchFilter behavior when Content-Type is * SOLR-1940: Fix SolrDispatchFilter behavior when Content-Type is
unknown (Lance Norskog and hossman) unknown (Lance Norskog and hossman)
* SOLR-2339: Fix sorting to explicitly generate an error if you
attempt to sort on a multiValued field. (hossman)
Other Changes Other Changes
---------------------- ----------------------

View File

@ -43,6 +43,7 @@ public class BoolField extends FieldType {
@Override @Override
public SortField getSortField(SchemaField field,boolean reverse) { public SortField getSortField(SchemaField field,boolean reverse) {
field.checkSortability();
return getStringSort(field,reverse); return getStringSort(field,reverse);
} }

View File

@ -41,6 +41,7 @@ public class ByteField extends FieldType {
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
@Override @Override
public SortField getSortField(SchemaField field, boolean reverse) { public SortField getSortField(SchemaField field, boolean reverse) {
field.checkSortability();
return new SortField(field.name, SortField.BYTE, reverse); return new SortField(field.name, SortField.BYTE, reverse);
} }
@ -78,4 +79,4 @@ public class ByteField extends FieldType {
public Byte toObject(Fieldable f) { public Byte toObject(Fieldable f) {
return Byte.valueOf(toExternal(f)); return Byte.valueOf(toExternal(f));
} }
} }

View File

@ -41,6 +41,7 @@ public class DoubleField extends FieldType {
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
@Override @Override
public SortField getSortField(SchemaField field, boolean reverse) { public SortField getSortField(SchemaField field, boolean reverse) {
field.checkSortability();
return new SortField(field.name, SortField.DOUBLE, reverse); return new SortField(field.name, SortField.DOUBLE, reverse);
} }

View File

@ -478,13 +478,17 @@ public abstract class FieldType extends FieldProperties {
/** /**
* Returns the SortField instance that should be used to sort fields * Returns the SortField instance that should be used to sort fields
* of this type. * of this type.
* @see SchemaField#checkSortability
*/ */
public abstract SortField getSortField(SchemaField field, boolean top); public abstract SortField getSortField(SchemaField field, boolean top);
/** /**
* Utility usable by subclasses when they want to get basic String sorting. * Utility usable by subclasses when they want to get basic String sorting
* using common checks.
* @see SchemaField#checkSortability
*/ */
protected SortField getStringSort(SchemaField field, boolean reverse) { protected SortField getStringSort(SchemaField field, boolean reverse) {
field.checkSortability();
return Sorting.getStringSortField(field.name, reverse, field.sortMissingLast(),field.sortMissingFirst()); return Sorting.getStringSortField(field.name, reverse, field.sortMissingLast(),field.sortMissingFirst());
} }

View File

@ -39,6 +39,7 @@ public class FloatField extends FieldType {
@Override @Override
public SortField getSortField(SchemaField field,boolean reverse) { public SortField getSortField(SchemaField field,boolean reverse) {
field.checkSortability();
return new SortField(field.name,SortField.FLOAT, reverse); return new SortField(field.name,SortField.FLOAT, reverse);
} }

View File

@ -39,6 +39,7 @@ public class IntField extends FieldType {
@Override @Override
public SortField getSortField(SchemaField field,boolean reverse) { public SortField getSortField(SchemaField field,boolean reverse) {
field.checkSortability();
return new SortField(field.name,SortField.INT, reverse); return new SortField(field.name,SortField.INT, reverse);
} }

View File

@ -41,7 +41,7 @@ public class LongField extends FieldType {
@Override @Override
public SortField getSortField(SchemaField field,boolean reverse) { public SortField getSortField(SchemaField field,boolean reverse) {
field.checkSortability();
return new SortField(field.name,SortField.LONG, reverse); return new SortField(field.name,SortField.LONG, reverse);
} }

View File

@ -17,9 +17,12 @@
package org.apache.solr.schema; package org.apache.solr.schema;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable; import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.apache.solr.response.TextResponseWriter; import org.apache.solr.response.TextResponseWriter;
import java.util.Map; import java.util.Map;
@ -120,10 +123,35 @@ public final class SchemaField extends FieldProperties {
type.write(writer,name,val); type.write(writer,name,val);
} }
/**
* Delegates to the FieldType for this field
* @see FieldType#getSortField
*/
public SortField getSortField(boolean top) { public SortField getSortField(boolean top) {
return type.getSortField(this, top); return type.getSortField(this, top);
} }
/**
* Sanity checks that the properties of this field type are plausible
* for a field that may be used in sorting, throwing an appropraite
* exception (including hte field name) if it is not. FieldType subclasses
* can choose to call this method in their getSortField implementation
* @see FieldType#getSortField
*/
public void checkSortability() throws SolrException {
if (! indexed() ) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"can not sort on unindexed field: "
+ getName());
}
if ( multiValued() ) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"can not sort on multivalued field: "
+ getName());
}
}
static SchemaField create(String name, FieldType ft, Map<String,String> props) { static SchemaField create(String name, FieldType ft, Map<String,String> props) {

View File

@ -44,7 +44,7 @@ public class ShortField extends FieldType {
@Override @Override
public SortField getSortField(SchemaField field, boolean reverse) { public SortField getSortField(SchemaField field, boolean reverse) {
field.checkSortability();
return new SortField(field.name, SortField.SHORT, reverse); return new SortField(field.name, SortField.SHORT, reverse);
} }

View File

@ -65,6 +65,7 @@ public class TextField extends FieldType {
@Override @Override
public SortField getSortField(SchemaField field, boolean reverse) { public SortField getSortField(SchemaField field, boolean reverse) {
/* :TODO: maybe warn if isTokenized(), but doesn't use LimitTokenCountFilter in it's chain? */
return getStringSort(field, reverse); return getStringSort(field, reverse);
} }

View File

@ -78,6 +78,7 @@ public class TrieDateField extends DateField {
@Override @Override
public SortField getSortField(SchemaField field, boolean top) { public SortField getSortField(SchemaField field, boolean top) {
field.checkSortability();
return new SortField(new LongValuesCreator( field.getName(), FieldCache.NUMERIC_UTILS_LONG_PARSER, CachedArrayCreator.CACHE_VALUES_AND_BITS ), top); return new SortField(new LongValuesCreator( field.getName(), FieldCache.NUMERIC_UTILS_LONG_PARSER, CachedArrayCreator.CACHE_VALUES_AND_BITS ), top);
} }

View File

@ -123,6 +123,8 @@ public class TrieField extends FieldType {
@Override @Override
public SortField getSortField(SchemaField field, boolean top) { public SortField getSortField(SchemaField field, boolean top) {
field.checkSortability();
int flags = CachedArrayCreator.CACHE_VALUES_AND_BITS; int flags = CachedArrayCreator.CACHE_VALUES_AND_BITS;
Object missingValue = null; Object missingValue = null;
boolean sortMissingLast = on( SORT_MISSING_LAST, properties ); boolean sortMissingLast = on( SORT_MISSING_LAST, properties );

View File

@ -330,16 +330,9 @@ public class QueryParsing {
} }
throw new SolrException throw new SolrException
(SolrException.ErrorCode.BAD_REQUEST, (SolrException.ErrorCode.BAD_REQUEST,
"sort param fiedl can't be found: " + field); "sort param field can't be found: " + field);
} }
lst.add(sf.getSortField(top));
// TODO: remove this - it should be up to the FieldType
if (!sf.indexed()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"can not sort on unindexed field: "
+ field);
}
lst.add(sf.getType().getSortField(sf, top));
} }
} }

View File

@ -402,8 +402,8 @@
<field name="text" type="text" indexed="true" stored="false"/> <field name="text" type="text" indexed="true" stored="false"/>
<field name="subject" type="text" indexed="true" stored="true"/> <field name="subject" type="text" indexed="true" stored="true"/>
<field name="title" type="nametext" indexed="true" stored="true"/> <field name="title" type="nametext" indexed="true" stored="true"/>
<field name="weight" type="float" indexed="true" stored="true"/> <field name="weight" type="float" indexed="true" stored="true" multiValued="false"/>
<field name="bday" type="date" indexed="true" stored="true"/> <field name="bday" type="date" indexed="true" stored="true" multiValued="false"/>
<field name="title_stemmed" type="text" indexed="true" stored="false"/> <field name="title_stemmed" type="text" indexed="true" stored="false"/>
<field name="title_lettertok" type="lettertok" indexed="true" stored="false"/> <field name="title_lettertok" type="lettertok" indexed="true" stored="false"/>
@ -480,7 +480,7 @@
<field name="numberpartfail" type="failtype1" indexed="true" stored="true"/> <field name="numberpartfail" type="failtype1" indexed="true" stored="true"/>
<field name="nullfirst" type="string" indexed="true" stored="true" sortMissingFirst="true"/> <field name="nullfirst" type="string" indexed="true" stored="true" sortMissingFirst="true" multiValued="false"/>
<field name="subword" type="subword" indexed="true" stored="true"/> <field name="subword" type="subword" indexed="true" stored="true"/>
<field name="subword_offsets" type="subword" indexed="true" stored="true" termOffsets="true"/> <field name="subword_offsets" type="subword" indexed="true" stored="true" termOffsets="true"/>
@ -508,27 +508,40 @@
both match, the first appearing in the schema will be used. both match, the first appearing in the schema will be used.
--> -->
<dynamicField name="*_i" type="int" indexed="true" stored="true"/> <dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_i1" type="int" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true"/> <dynamicField name="*_s" type="string" indexed="true" stored="true"/>
<dynamicField name="*_s1" type="string" indexed="true" stored="true" multiValued="false"/> <dynamicField name="*_s1" type="string" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_l" type="long" indexed="true" stored="true"/> <dynamicField name="*_l" type="long" indexed="true" stored="true"/>
<dynamicField name="*_l1" type="long" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_t" type="text" indexed="true" stored="true"/> <dynamicField name="*_t" type="text" indexed="true" stored="true"/>
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/> <dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/> <dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_f1" type="float" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/> <dynamicField name="*_d" type="double" indexed="true" stored="true"/>
<dynamicField name="*_d1" type="double" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/> <dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="*_dt1" type="date" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_bcd" type="bcdstr" indexed="true" stored="true"/> <dynamicField name="*_bcd" type="bcdstr" indexed="true" stored="true"/>
<!-- some trie-coded dynamic fields for faster range queries --> <!-- some trie-coded dynamic fields for faster range queries -->
<dynamicField name="*_ti" type="tint" indexed="true" stored="true"/> <dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>
<dynamicField name="*_ti1" type="tint" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/> <dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/>
<dynamicField name="*_tl1" type="tlong" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/> <dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/>
<dynamicField name="*_tf1" type="tfloat" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/> <dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/>
<dynamicField name="*_td1" type="tdouble" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/> <dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/>
<dynamicField name="*_tdt1" type="tdate" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_si" type="sint" indexed="true" stored="true"/> <dynamicField name="*_si" type="sint" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_sl" type="slong" indexed="true" stored="true"/> <dynamicField name="*_sl" type="slong" indexed="true" stored="true"/>
<dynamicField name="*_sf" type="sfloat" indexed="true" stored="true"/> <dynamicField name="*_sf" type="sfloat" indexed="true" stored="true"/>
<dynamicField name="*_sf1" type="sfloat" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_sd" type="sdouble" indexed="true" stored="true"/> <dynamicField name="*_sd" type="sdouble" indexed="true" stored="true"/>
<dynamicField name="*_sd1" type="sdouble" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_pi" type="pint" indexed="true" stored="true"/> <dynamicField name="*_pi" type="pint" indexed="true" stored="true"/>
<dynamicField name="*_pf" type="pfloat" indexed="true" stored="true"/> <dynamicField name="*_pf" type="pfloat" indexed="true" stored="true"/>

View File

@ -545,6 +545,8 @@
<dynamicField name="*_i" type="int" indexed="true" stored="true"/> <dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_is" type="int" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_is" type="int" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_s1" type="string" indexed="true" stored="true" multiValued="false"/>
<!-- :TODO: why are these identical?!?!?! -->
<dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_ss" type="string" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_ss" type="string" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="true"/> <dynamicField name="*_l" type="long" indexed="true" stored="true"/>

View File

@ -134,7 +134,7 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 {
*/ */
public abstract void doTest() throws Exception; public abstract void doTest() throws Exception;
public static String[] fieldNames = new String[]{"n_ti", "n_f", "n_tf", "n_d", "n_td", "n_l", "n_tl", "n_dt", "n_tdt"}; public static String[] fieldNames = new String[]{"n_ti1", "n_f1", "n_tf1", "n_d1", "n_td1", "n_l1", "n_tl1", "n_dt1", "n_tdt1"};
public static RandVal[] randVals = new RandVal[]{rint, rfloat, rfloat, rdouble, rdouble, rlong, rlong, rdate, rdate}; public static RandVal[] randVals = new RandVal[]{rint, rfloat, rfloat, rdouble, rdouble, rlong, rlong, rdate, rdate};
protected String[] getFieldNames() { protected String[] getFieldNames() {
@ -580,7 +580,8 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 {
String cmp; String cmp;
cmp = compare(a.getResponse(), b.getResponse(), flags, handle); cmp = compare(a.getResponse(), b.getResponse(), flags, handle);
if (cmp != null) { if (cmp != null) {
log.info("Mismatched responses:\n" + a + "\n" + b); //log.info("Mismatched responses:\n" + a + "\n" + b);
System.err.println("Mismatched responses:\n" + a + "\n" + b); // :nocommit:
TestCase.fail(cmp); TestCase.fail(cmp);
} }
} }

View File

@ -29,6 +29,8 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable; import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.LogMergePolicy; import org.apache.lucene.index.LogMergePolicy;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.params.AppendedSolrParams; import org.apache.solr.common.params.AppendedSolrParams;
import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.DefaultSolrParams; import org.apache.solr.common.params.DefaultSolrParams;
@ -47,6 +49,8 @@ import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.DocIterator; import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.update.SolrIndexWriter; import org.apache.solr.update.SolrIndexWriter;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -658,6 +662,39 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
"*[count(//doc)=1]"); "*[count(//doc)=1]");
} }
@Test
public void testAbuseOfSort() {
assertU(adoc("id", "9999991",
"sortabuse_b", "true",
"sortabuse_t", "zzz xxx ccc vvv bbb nnn aaa sss ddd fff ggg"));
assertU(adoc("id", "9999992",
"sortabuse_b", "true",
"sortabuse_t", "zzz xxx ccc vvv bbb nnn qqq www eee rrr ttt"));
assertU(commit());
try {
assertQ("sort on something that shouldn't work",
req("q", "sortabuse_b:true",
"sort", "sortabuse_t asc"),
"*[count(//doc)=2]");
fail("no error encountered when sorting on sortabuse_t");
} catch (Exception outer) {
// EXPECTED
Throwable root = getRootCause(outer);
assertEquals("sort exception root cause",
SolrException.class, root.getClass());
SolrException e = (SolrException) root;
assertEquals("incorrect error type",
SolrException.ErrorCode.BAD_REQUEST,
SolrException.ErrorCode.getErrorCode(e.code()));
assertTrue("exception doesn't contain field name",
-1 != e.getMessage().indexOf("sortabuse_t"));
}
}
// /** this doesn't work, but if it did, this is how we'd test it. */ // /** this doesn't work, but if it did, this is how we'd test it. */
// public void testOverwriteFalse() { // public void testOverwriteFalse() {

View File

@ -123,9 +123,9 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
// test range // test range
assertU("<delete><id>44</id></delete>"); assertU("<delete><id>44</id></delete>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"val_s\">apple</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"val_s\">apple</field><field name=\"val_s1\">apple</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"val_s\">banana</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"val_s\">banana</field><field name=\"val_s1\">banana</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"val_s\">pear</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"val_s\">pear</field><field name=\"val_s1\">pear</field></doc></add>");
assertU("<commit/>"); assertU("<commit/>");
assertQ(req("val_s:[a TO z]") assertQ(req("val_s:[a TO z]")
,"//*[@numFound='3'] " ,"//*[@numFound='3'] "
@ -228,7 +228,7 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
args = new HashMap<String,String>(); args = new HashMap<String,String>();
args.put("version","2.0"); args.put("version","2.0");
args.put("defType","lucenePlusSort"); args.put("defType","lucenePlusSort");
req = new LocalSolrQueryRequest(h.getCore(), "val_s:[a TO z];val_s asc", req = new LocalSolrQueryRequest(h.getCore(), "val_s:[a TO z];val_s1 asc",
"standard", 0, 0 , args); "standard", 0, 0 , args);
assertQ(req assertQ(req
,"//*[@numFound='3'] " ,"//*[@numFound='3'] "
@ -237,7 +237,7 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
args = new HashMap<String,String>(); args = new HashMap<String,String>();
args.put("version","2.0"); args.put("version","2.0");
args.put("defType","lucenePlusSort"); args.put("defType","lucenePlusSort");
req = new LocalSolrQueryRequest(h.getCore(), "val_s:[a TO z];val_s desc", req = new LocalSolrQueryRequest(h.getCore(), "val_s:[a TO z];val_s1 desc",
"standard", 0, 0 , args); "standard", 0, 0 , args);
assertQ(req assertQ(req
,"//*[@numFound='3'] " ,"//*[@numFound='3'] "
@ -509,133 +509,133 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
// test integer ranges and sorting // test integer ranges and sorting
assertU("<delete><id>44</id></delete>"); assertU("<delete><id>44</id></delete>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">1234567890</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">1234567890</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">10</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">10</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">2</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">2</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">15</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">15</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">-1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">-1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">-987654321</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">-987654321</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">2147483647</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">2147483647</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">-2147483648</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">-2147483648</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i\">0</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_i1\">0</field></doc></add>");
assertU("<commit/>"); assertU("<commit/>");
assertQ(req("id:44") assertQ(req("id:44")
,"*[count(//doc)=10]" ,"*[count(//doc)=10]"
); );
assertQ(req("num_i:2147483647") assertQ(req("num_i1:2147483647")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//int[.='2147483647']" ,"//int[.='2147483647']"
); );
assertQ(req("num_i:\"-2147483648\"") assertQ(req("num_i1:\"-2147483648\"")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//int[.='-2147483648']" ,"//int[.='-2147483648']"
); );
assertQ(req("id:44;num_i asc;") assertQ(req("id:44;num_i1 asc;")
,"//doc[1]/int[.='-2147483648'] " ,"//doc[1]/int[.='-2147483648'] "
,"//doc[last()]/int[.='2147483647']" ,"//doc[last()]/int[.='2147483647']"
); );
assertQ(req("id:44;num_i desc;") assertQ(req("id:44;num_i1 desc;")
,"//doc[1]/int[.='2147483647'] " ,"//doc[1]/int[.='2147483647'] "
,"//doc[last()]/int[.='-2147483648']" ,"//doc[last()]/int[.='-2147483648']"
); );
assertQ(req("num_i:[0 TO 9]") assertQ(req("num_i1:[0 TO 9]")
,"*[count(//doc)=3]" ,"*[count(//doc)=3]"
); );
assertQ(req("num_i:[-2147483648 TO 2147483647]") assertQ(req("num_i1:[-2147483648 TO 2147483647]")
,"*[count(//doc)=10]" ,"*[count(//doc)=10]"
); );
assertQ(req("num_i:[-10 TO -1]") assertQ(req("num_i1:[-10 TO -1]")
,"*[count(//doc)=1]" ,"*[count(//doc)=1]"
); );
// test long ranges and sorting // test long ranges and sorting
assertU("<delete><id>44</id></delete>"); assertU("<delete><id>44</id></delete>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">1234567890</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">1234567890</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">10</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">10</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">2</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">2</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">15</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">15</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">-1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">-1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">-987654321</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">-987654321</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">9223372036854775807</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">9223372036854775807</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">-9223372036854775808</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">-9223372036854775808</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l\">0</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_l1\">0</field></doc></add>");
assertU("<commit/>"); assertU("<commit/>");
assertQ(req("id:44") assertQ(req("id:44")
,"*[count(//doc)=10]" ,"*[count(//doc)=10]"
); );
assertQ(req("num_l:9223372036854775807") assertQ(req("num_l1:9223372036854775807")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//long[.='9223372036854775807']" ,"//long[.='9223372036854775807']"
); );
assertQ(req("num_l:\"-9223372036854775808\"") assertQ(req("num_l1:\"-9223372036854775808\"")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//long[.='-9223372036854775808']" ,"//long[.='-9223372036854775808']"
); );
assertQ(req("id:44;num_l asc;") assertQ(req("id:44;num_l1 asc;")
,"//doc[1]/long[.='-9223372036854775808'] " ,"//doc[1]/long[.='-9223372036854775808'] "
,"//doc[last()]/long[.='9223372036854775807']" ,"//doc[last()]/long[.='9223372036854775807']"
); );
assertQ(req("id:44;num_l desc;") assertQ(req("id:44;num_l1 desc;")
,"//doc[1]/long[.='9223372036854775807'] " ,"//doc[1]/long[.='9223372036854775807'] "
,"//doc[last()]/long[.='-9223372036854775808']" ,"//doc[last()]/long[.='-9223372036854775808']"
); );
assertQ(req("num_l:[-1 TO 9]") assertQ(req("num_l1:[-1 TO 9]")
,"*[count(//doc)=4]" ,"*[count(//doc)=4]"
); );
assertQ(req("num_l:[-9223372036854775808 TO 9223372036854775807]") assertQ(req("num_l1:[-9223372036854775808 TO 9223372036854775807]")
,"*[count(//doc)=10]" ,"*[count(//doc)=10]"
); );
assertQ(req("num_l:[-10 TO -1]") assertQ(req("num_l1:[-10 TO -1]")
,"*[count(//doc)=1]" ,"*[count(//doc)=1]"
); );
// test binary float ranges and sorting // test binary float ranges and sorting
assertU("<delete><id>44</id></delete>"); assertU("<delete><id>44</id></delete>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">1.4142135</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">1.4142135</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">Infinity</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">Infinity</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">-Infinity</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">-Infinity</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">NaN</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">NaN</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">2</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">2</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">-1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">-1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">-987654321</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">-987654321</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">-999999.99</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">-999999.99</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">-1e20</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">-1e20</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf\">0</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sf1\">0</field></doc></add>");
assertU("<commit/>"); assertU("<commit/>");
assertQ(req("id:44") assertQ(req("id:44")
,"*[count(//doc)=10]" ,"*[count(//doc)=10]"
); );
assertQ(req("num_sf:Infinity") assertQ(req("num_sf1:Infinity")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//float[.='Infinity']" ,"//float[.='Infinity']"
); );
assertQ(req("num_sf:\"-Infinity\"") assertQ(req("num_sf1:\"-Infinity\"")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//float[.='-Infinity']" ,"//float[.='-Infinity']"
); );
assertQ(req("num_sf:\"NaN\"") assertQ(req("num_sf1:\"NaN\"")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//float[.='NaN']" ,"//float[.='NaN']"
); );
assertQ(req("num_sf:\"-1e20\"") assertQ(req("num_sf1:\"-1e20\"")
,"//@numFound[.='1']" ,"//@numFound[.='1']"
); );
assertQ(req("id:44;num_sf asc;") assertQ(req("id:44;num_sf1 asc;")
,"//doc[1]/float[.='-Infinity'] " ,"//doc[1]/float[.='-Infinity'] "
,"//doc[last()]/float[.='NaN']" ,"//doc[last()]/float[.='NaN']"
); );
assertQ(req("id:44;num_sf desc;") assertQ(req("id:44;num_sf1 desc;")
,"//doc[1]/float[.='NaN'] " ,"//doc[1]/float[.='NaN'] "
,"//doc[last()]/float[.='-Infinity']" ,"//doc[last()]/float[.='-Infinity']"
); );
assertQ(req("num_sf:[-1 TO 2]") assertQ(req("num_sf1:[-1 TO 2]")
,"*[count(//doc)=4]" ,"*[count(//doc)=4]"
); );
assertQ(req("num_sf:[-Infinity TO Infinity]") assertQ(req("num_sf1:[-Infinity TO Infinity]")
,"*[count(//doc)=9]" ,"*[count(//doc)=9]"
); );
@ -644,50 +644,50 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
// test binary double ranges and sorting // test binary double ranges and sorting
assertU("<delete><id>44</id></delete>"); assertU("<delete><id>44</id></delete>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">1.4142135</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">1.4142135</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">Infinity</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">Infinity</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">-Infinity</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">-Infinity</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">NaN</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">NaN</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">2</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">2</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">-1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">-1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">1e-100</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">1e-100</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">-999999.99</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">-999999.99</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">-1e100</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">-1e100</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd\">0</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"num_sd1\">0</field></doc></add>");
assertU("<commit/>"); assertU("<commit/>");
assertQ(req("id:44") assertQ(req("id:44")
,"*[count(//doc)=10]" ,"*[count(//doc)=10]"
); );
assertQ(req("num_sd:Infinity") assertQ(req("num_sd1:Infinity")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//double[.='Infinity']" ,"//double[.='Infinity']"
); );
assertQ(req("num_sd:\"-Infinity\"") assertQ(req("num_sd1:\"-Infinity\"")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//double[.='-Infinity']" ,"//double[.='-Infinity']"
); );
assertQ(req("num_sd:\"NaN\"") assertQ(req("num_sd1:\"NaN\"")
,"//@numFound[.='1'] " ,"//@numFound[.='1'] "
,"//double[.='NaN']" ,"//double[.='NaN']"
); );
assertQ(req("num_sd:\"-1e100\"") assertQ(req("num_sd1:\"-1e100\"")
,"//@numFound[.='1']" ,"//@numFound[.='1']"
); );
assertQ(req("num_sd:\"1e-100\"") assertQ(req("num_sd1:\"1e-100\"")
,"//@numFound[.='1']" ,"//@numFound[.='1']"
); );
assertQ(req("id:44;num_sd asc;") assertQ(req("id:44;num_sd1 asc;")
,"//doc[1]/double[.='-Infinity'] " ,"//doc[1]/double[.='-Infinity'] "
,"//doc[last()]/double[.='NaN']" ,"//doc[last()]/double[.='NaN']"
); );
assertQ(req("id:44;num_sd desc;") assertQ(req("id:44;num_sd1 desc;")
,"//doc[1]/double[.='NaN'] " ,"//doc[1]/double[.='NaN'] "
,"//doc[last()]/double[.='-Infinity']" ,"//doc[last()]/double[.='-Infinity']"
); );
assertQ(req("num_sd:[-1 TO 2]") assertQ(req("num_sd1:[-1 TO 2]")
,"*[count(//doc)=5]" ,"*[count(//doc)=5]"
); );
assertQ(req("num_sd:[-Infinity TO Infinity]") assertQ(req("num_sd1:[-Infinity TO Infinity]")
,"*[count(//doc)=9]" ,"*[count(//doc)=9]"
); );
@ -695,38 +695,38 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
// test sorting on multiple fields // test sorting on multiple fields
assertU("<delete><id>44</id></delete>"); assertU("<delete><id>44</id></delete>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i\">10</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i1\">10</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i\">1</field><field name=\"b_i\">100</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i1\">1</field><field name=\"b_i1\">100</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i\">-1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i1\">-1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i\">15</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i1\">15</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i\">1</field><field name=\"b_i\">50</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i1\">1</field><field name=\"b_i1\">50</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i\">0</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id\">44</field><field name=\"a_i1\">0</field></doc></add>");
assertU("<commit/>"); assertU("<commit/>");
assertQ(req("id:44") assertQ(req("id:44")
,"*[count(//doc)=6]" ,"*[count(//doc)=6]"
); );
assertQ(req("id:44; a_i asc,b_i desc") assertQ(req("id:44; a_i1 asc,b_i1 desc")
,"*[count(//doc)=6] " ,"*[count(//doc)=6] "
,"//doc[3]/int[.='100'] " ,"//doc[3]/int[.='100'] "
,"//doc[4]/int[.='50']" ,"//doc[4]/int[.='50']"
); );
assertQ(req("id:44;a_i asc , b_i asc;") assertQ(req("id:44;a_i1 asc , b_i1 asc;")
,"*[count(//doc)=6] " ,"*[count(//doc)=6] "
,"//doc[3]/int[.='50'] " ,"//doc[3]/int[.='50'] "
,"//doc[4]/int[.='100']" ,"//doc[4]/int[.='100']"
); );
assertQ(req("id:44;a_i asc;") assertQ(req("id:44;a_i1 asc;")
,"*[count(//doc)=6] " ,"*[count(//doc)=6] "
,"//doc[1]/int[.='-1'] " ,"//doc[1]/int[.='-1'] "
,"//doc[last()]/int[.='15']" ,"//doc[last()]/int[.='15']"
); );
assertQ(req("id:44;a_i asc , score top;") assertQ(req("id:44;a_i1 asc , score top;")
,"*[count(//doc)=6] " ,"*[count(//doc)=6] "
,"//doc[1]/int[.='-1'] " ,"//doc[1]/int[.='-1'] "
,"//doc[last()]/int[.='15']" ,"//doc[last()]/int[.='15']"
); );
assertQ(req("id:44; score top , a_i top, b_i bottom ;") assertQ(req("id:44; score top , a_i1 top, b_i1 bottom ;")
,"*[count(//doc)=6] " ,"*[count(//doc)=6] "
,"//doc[last()]/int[.='-1'] " ,"//doc[last()]/int[.='-1'] "
,"//doc[1]/int[.='15'] " ,"//doc[1]/int[.='15'] "
@ -738,13 +738,13 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
// test sorting with some docs missing the sort field // test sorting with some docs missing the sort field
assertU("<delete><query>id_i:[1000 TO 1010]</query></delete>"); assertU("<delete><query>id_i:[1000 TO 1010]</query></delete>");
assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1000</field><field name=\"a_i\">1</field><field name=\"nullfirst\">Z</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1000</field><field name=\"a_i1\">1</field><field name=\"nullfirst\">Z</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1001</field><field name=\"a_i\">10</field><field name=\"nullfirst\">A</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1001</field><field name=\"a_i1\">10</field><field name=\"nullfirst\">A</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1002</field><field name=\"a_i\">1</field><field name=\"b_si\">100</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1002</field><field name=\"a_i1\">1</field><field name=\"b_si\">100</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1003</field><field name=\"a_i\">-1</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1003</field><field name=\"a_i1\">-1</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1004</field><field name=\"a_i\">15</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1004</field><field name=\"a_i1\">15</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1005</field><field name=\"a_i\">1</field><field name=\"b_si\">50</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1005</field><field name=\"a_i1\">1</field><field name=\"b_si\">50</field></doc></add>");
assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1006</field><field name=\"a_i\">0</field></doc></add>"); assertU("<add overwrite=\"false\"><doc><field name=\"id_i\">1006</field><field name=\"a_i1\">0</field></doc></add>");
assertU("<commit/>"); assertU("<commit/>");
assertQ(req("id_i:[1000 TO 1010]") assertQ(req("id_i:[1000 TO 1010]")
,"*[count(//doc)=7]" ,"*[count(//doc)=7]"
@ -759,13 +759,13 @@ public class ConvertedLegacyTest extends SolrTestCaseJ4 {
,"//doc[1]/int[.='100'] " ,"//doc[1]/int[.='100'] "
,"//doc[2]/int[.='50']" ,"//doc[2]/int[.='50']"
); );
assertQ(req("id_i:[1000 TO 1010]; a_i asc,b_si desc") assertQ(req("id_i:[1000 TO 1010]; a_i1 asc,b_si desc")
,"*[count(//doc)=7] " ,"*[count(//doc)=7] "
,"//doc[3]/int[.='100'] " ,"//doc[3]/int[.='100'] "
,"//doc[4]/int[.='50'] " ,"//doc[4]/int[.='50'] "
,"//doc[5]/int[.='1000']" ,"//doc[5]/int[.='1000']"
); );
assertQ(req("id_i:[1000 TO 1010]; a_i asc,b_si asc") assertQ(req("id_i:[1000 TO 1010]; a_i1 asc,b_si asc")
,"*[count(//doc)=7] " ,"*[count(//doc)=7] "
,"//doc[3]/int[.='50'] " ,"//doc[3]/int[.='50'] "
,"//doc[4]/int[.='100'] " ,"//doc[4]/int[.='100'] "

View File

@ -1073,4 +1073,12 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
} }
return new File(base, "solr/").getAbsolutePath(); return new File(base, "solr/").getAbsolutePath();
} }
public static Throwable getRootCause(Throwable t) {
Throwable result = t;
for (Throwable cause = t; null != cause; cause = cause.getCause()) {
result = cause;
}
return result;
}
} }

View File

@ -38,7 +38,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
String ndouble = "n_d"; String ndouble = "n_d";
String tdouble = "n_td"; String tdouble = "n_td";
String nlong = "n_l"; String nlong = "n_l";
String tlong = "n_tl"; String tlong = "other_tl1";
String ndate = "n_dt"; String ndate = "n_dt";
String tdate = "n_tdt"; String tdate = "n_tdt";
@ -98,8 +98,8 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
query("q","*:*", "sort","{!func}add("+i1+",5)"+" desc"); query("q","*:*", "sort","{!func}add("+i1+",5)"+" desc");
query("q","*:*", "sort",i1+" asc"); query("q","*:*", "sort",i1+" asc");
query("q","*:*", "sort",i1+" desc", "fl","*,score"); query("q","*:*", "sort",i1+" desc", "fl","*,score");
query("q","*:*", "sort",tlong+" asc", "fl","score"); // test legacy behavior - "score"=="*,score" query("q","*:*", "sort","n_tl1 asc", "fl","score"); // test legacy behavior - "score"=="*,score"
query("q","*:*", "sort",tlong+" desc"); query("q","*:*", "sort","n_tl1 desc");
handle.put("maxScore", SKIPVAL); handle.put("maxScore", SKIPVAL);
query("q","{!func}"+i1);// does not expect maxScore. So if it comes ,ignore it. JavaBinCodec.writeSolrDocumentList() query("q","{!func}"+i1);// does not expect maxScore. So if it comes ,ignore it. JavaBinCodec.writeSolrDocumentList()
//is agnostic of request params. //is agnostic of request params.

View File

@ -30,6 +30,10 @@ import java.util.*;
public class TestGroupingSearch extends SolrTestCaseJ4 { public class TestGroupingSearch extends SolrTestCaseJ4 {
public static final String FOO_STRING_FIELD = "foo_s1";
public static final String SMALL_STRING_FIELD = "small_s1";
public static final String SMALL_INT_FIELD = "small_i";
@BeforeClass @BeforeClass
public static void beforeTests() throws Exception { public static void beforeTests() throws Exception {
initCore("solrconfig.xml","schema12.xml"); initCore("solrconfig.xml","schema12.xml");
@ -376,9 +380,9 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
types.add(new FldType("id",ONE_ONE, new SVal('A','Z',4,4))); types.add(new FldType("id",ONE_ONE, new SVal('A','Z',4,4)));
types.add(new FldType("score_f",ONE_ONE, new FVal(1,100))); // field used to score types.add(new FldType("score_f",ONE_ONE, new FVal(1,100))); // field used to score
types.add(new FldType("foo_i",ZERO_ONE, new IRange(0,indexSize))); types.add(new FldType("foo_i",ZERO_ONE, new IRange(0,indexSize)));
types.add(new FldType("foo_s",ZERO_ONE, new SVal('a','z',1,2))); types.add(new FldType(FOO_STRING_FIELD,ZERO_ONE, new SVal('a','z',1,2)));
types.add(new FldType("small_s",ZERO_ONE, new SVal('a',(char)('c'+indexSize/10),1,1))); types.add(new FldType(SMALL_STRING_FIELD,ZERO_ONE, new SVal('a',(char)('c'+indexSize/10),1,1)));
types.add(new FldType("small_i",ZERO_ONE, new IRange(0,5+indexSize/10))); types.add(new FldType(SMALL_INT_FIELD,ZERO_ONE, new IRange(0,5+indexSize/10)));
clearIndex(); clearIndex();
Map<Comparable, Doc> model = indexDocs(types, null, indexSize); Map<Comparable, Doc> model = indexDocs(types, null, indexSize);
@ -389,36 +393,36 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
clearIndex(); clearIndex();
model.clear(); model.clear();
Doc d1 = createDoc(types); Doc d1 = createDoc(types);
d1.getValues("small_s").set(0,"c"); d1.getValues(SMALL_STRING_FIELD).set(0,"c");
d1.getValues("small_i").set(0,5); d1.getValues(SMALL_INT_FIELD).set(0,5);
d1.order = 0; d1.order = 0;
updateJ(toJSON(d1), params("commit","true")); updateJ(toJSON(d1), params("commit","true"));
model.put(d1.id, d1); model.put(d1.id, d1);
d1 = createDoc(types); d1 = createDoc(types);
d1.getValues("small_s").set(0,"b"); d1.getValues(SMALL_STRING_FIELD).set(0,"b");
d1.getValues("small_i").set(0,5); d1.getValues(SMALL_INT_FIELD).set(0,5);
d1.order = 1; d1.order = 1;
updateJ(toJSON(d1), params("commit","false")); updateJ(toJSON(d1), params("commit","false"));
model.put(d1.id, d1); model.put(d1.id, d1);
d1 = createDoc(types); d1 = createDoc(types);
d1.getValues("small_s").set(0,"c"); d1.getValues(SMALL_STRING_FIELD).set(0,"c");
d1.getValues("small_i").set(0,5); d1.getValues(SMALL_INT_FIELD).set(0,5);
d1.order = 2; d1.order = 2;
updateJ(toJSON(d1), params("commit","false")); updateJ(toJSON(d1), params("commit","false"));
model.put(d1.id, d1); model.put(d1.id, d1);
d1 = createDoc(types); d1 = createDoc(types);
d1.getValues("small_s").set(0,"c"); d1.getValues(SMALL_STRING_FIELD).set(0,"c");
d1.getValues("small_i").set(0,5); d1.getValues(SMALL_INT_FIELD).set(0,5);
d1.order = 3; d1.order = 3;
updateJ(toJSON(d1), params("commit","false")); updateJ(toJSON(d1), params("commit","false"));
model.put(d1.id, d1); model.put(d1.id, d1);
d1 = createDoc(types); d1 = createDoc(types);
d1.getValues("small_s").set(0,"b"); d1.getValues(SMALL_STRING_FIELD).set(0,"b");
d1.getValues("small_i").set(0,2); d1.getValues(SMALL_INT_FIELD).set(0,2);
d1.order = 4; d1.order = 4;
updateJ(toJSON(d1), params("commit","true")); updateJ(toJSON(d1), params("commit","true"));
model.put(d1.id, d1); model.put(d1.id, d1);
@ -447,11 +451,11 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
// Test specific case // Test specific case
if (false) { if (false) {
groupField="small_i"; groupField=SMALL_INT_FIELD;
sortComparator=createComparator(Arrays.asList(createComparator("small_s", true, true, false, true))); sortComparator=createComparator(Arrays.asList(createComparator(SMALL_STRING_FIELD, true, true, false, true)));
sortStr = "small_s asc"; sortStr = SMALL_STRING_FIELD + " asc";
groupComparator = createComparator(Arrays.asList(createComparator("small_s", true, true, false, false))); groupComparator = createComparator(Arrays.asList(createComparator(SMALL_STRING_FIELD, true, true, false, false)));
groupSortStr = "small_s asc"; groupSortStr = SMALL_STRING_FIELD + " asc";
rows=1; start=0; group_offset=1; group_limit=1; rows=1; start=0; group_offset=1; group_limit=1;
} }

View File

@ -43,7 +43,7 @@ public class BasicDistributedZkTest extends AbstractDistributedZkTestCase {
String ndouble = "n_d"; String ndouble = "n_d";
String tdouble = "n_td"; String tdouble = "n_td";
String nlong = "n_l"; String nlong = "n_l";
String tlong = "n_tl"; String tlong = "other_tl1";
String ndate = "n_dt"; String ndate = "n_dt";
String tdate = "n_tdt"; String tdate = "n_tdt";
@ -133,8 +133,8 @@ public class BasicDistributedZkTest extends AbstractDistributedZkTestCase {
query("q","*:*", "sort",i1+" desc"); query("q","*:*", "sort",i1+" desc");
query("q","*:*", "sort",i1+" asc"); query("q","*:*", "sort",i1+" asc");
query("q","*:*", "sort",i1+" desc", "fl","*,score"); query("q","*:*", "sort",i1+" desc", "fl","*,score");
query("q","*:*", "sort",tlong+" asc", "fl","score"); // test legacy behavior - "score"=="*,score" query("q","*:*", "sort","n_tl1 asc", "fl","score"); // test legacy behavior - "score"=="*,score"
query("q","*:*", "sort",tlong+" desc"); query("q","*:*", "sort","n_tl1 desc");
handle.put("maxScore", SKIPVAL); handle.put("maxScore", SKIPVAL);
query("q","{!func}"+i1);// does not expect maxScore. So if it comes ,ignore it. JavaBinCodec.writeSolrDocumentList() query("q","{!func}"+i1);// does not expect maxScore. So if it comes ,ignore it. JavaBinCodec.writeSolrDocumentList()
//is agnostic of request params. //is agnostic of request params.

View File

@ -43,9 +43,9 @@ public class StandardRequestHandlerTest extends AbstractSolrTestCase {
public void testSorting() throws Exception { public void testSorting() throws Exception {
SolrCore core = h.getCore(); SolrCore core = h.getCore();
assertU(adoc("id", "10", "title", "test", "val_s", "aaa")); assertU(adoc("id", "10", "title", "test", "val_s1", "aaa"));
assertU(adoc("id", "11", "title", "test", "val_s", "bbb")); assertU(adoc("id", "11", "title", "test", "val_s1", "bbb"));
assertU(adoc("id", "12", "title", "test", "val_s", "ccc")); assertU(adoc("id", "12", "title", "test", "val_s1", "ccc"));
assertU(commit()); assertU(commit());
Map<String,String> args = new HashMap<String, String>(); Map<String,String> args = new HashMap<String, String>();
@ -58,7 +58,7 @@ public class StandardRequestHandlerTest extends AbstractSolrTestCase {
,"//*[@numFound='3']" ,"//*[@numFound='3']"
); );
args.put( CommonParams.SORT, "val_s asc" ); args.put( CommonParams.SORT, "val_s1 asc" );
assertQ("with sort param [asc]", req assertQ("with sort param [asc]", req
,"//*[@numFound='3']" ,"//*[@numFound='3']"
,"//result/doc[1]/int[@name='id'][.='10']" ,"//result/doc[1]/int[@name='id'][.='10']"
@ -66,7 +66,7 @@ public class StandardRequestHandlerTest extends AbstractSolrTestCase {
,"//result/doc[3]/int[@name='id'][.='12']" ,"//result/doc[3]/int[@name='id'][.='12']"
); );
args.put( CommonParams.SORT, "val_s desc" ); args.put( CommonParams.SORT, "val_s1 desc" );
assertQ("with sort param [desc]", req assertQ("with sort param [desc]", req
,"//*[@numFound='3']" ,"//*[@numFound='3']"
,"//result/doc[1]/int[@name='id'][.='12']" ,"//result/doc[1]/int[@name='id'][.='12']"
@ -84,7 +84,7 @@ public class StandardRequestHandlerTest extends AbstractSolrTestCase {
// Using legacy ';' param // Using legacy ';' param
args.remove( CommonParams.SORT ); args.remove( CommonParams.SORT );
args.put( QueryParsing.DEFTYPE, "lucenePlusSort" ); args.put( QueryParsing.DEFTYPE, "lucenePlusSort" );
args.put( CommonParams.Q, "title:test; val_s desc" ); args.put( CommonParams.Q, "title:test; val_s1 desc" );
assertQ("with sort param [desc]", req assertQ("with sort param [desc]", req
,"//*[@numFound='3']" ,"//*[@numFound='3']"
,"//result/doc[1]/int[@name='id'][.='12']" ,"//result/doc[1]/int[@name='id'][.='12']"
@ -92,8 +92,8 @@ public class StandardRequestHandlerTest extends AbstractSolrTestCase {
,"//result/doc[3]/int[@name='id'][.='10']" ,"//result/doc[3]/int[@name='id'][.='10']"
); );
args.put( CommonParams.Q, "title:test; val_s asc" ); args.put( CommonParams.Q, "title:test; val_s1 asc" );
assertQ("with sort param [desc]", req assertQ("with sort param [asc]", req
,"//*[@numFound='3']" ,"//*[@numFound='3']"
,"//result/doc[1]/int[@name='id'][.='10']" ,"//result/doc[1]/int[@name='id'][.='10']"
,"//result/doc[2]/int[@name='id'][.='11']" ,"//result/doc[2]/int[@name='id'][.='11']"

View File

@ -120,13 +120,13 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 {
@Test @Test
public void testSorting() throws IOException public void testSorting() throws IOException
{ {
assertU(adoc("id", "a", "title", "ipod", "str_s", "a" )); assertU(adoc("id", "a", "title", "ipod", "str_s1", "a" ));
assertU(adoc("id", "b", "title", "ipod ipod", "str_s", "b" )); assertU(adoc("id", "b", "title", "ipod ipod", "str_s1", "b" ));
assertU(adoc("id", "c", "title", "ipod ipod ipod", "str_s", "c" )); assertU(adoc("id", "c", "title", "ipod ipod ipod", "str_s1", "c" ));
assertU(adoc("id", "x", "title", "boosted", "str_s", "x" )); assertU(adoc("id", "x", "title", "boosted", "str_s1", "x" ));
assertU(adoc("id", "y", "title", "boosted boosted", "str_s", "y" )); assertU(adoc("id", "y", "title", "boosted boosted", "str_s1", "y" ));
assertU(adoc("id", "z", "title", "boosted boosted boosted", "str_s", "z" )); assertU(adoc("id", "z", "title", "boosted boosted boosted", "str_s1", "z" ));
assertU(commit()); assertU(commit());
String query = "title:ipod"; String query = "title:ipod";
@ -188,7 +188,7 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 {
// Try normal sort by 'id' // Try normal sort by 'id'
// default 'forceBoost' should be false // default 'forceBoost' should be false
assertEquals( false, booster.forceElevation ); assertEquals( false, booster.forceElevation );
args.put( CommonParams.SORT, "str_s asc" ); args.put( CommonParams.SORT, "str_s1 asc" );
assertQ( null, req assertQ( null, req
,"//*[@numFound='4']" ,"//*[@numFound='4']"
,"//result/doc[1]/str[@name='id'][.='a']" ,"//result/doc[1]/str[@name='id'][.='a']"

View File

@ -35,10 +35,10 @@ public class SortByFunctionTest extends AbstractSolrTestCase {
} }
public void test() throws Exception { public void test() throws Exception {
assertU(adoc("id", "1", "x_td", "0", "y_td", "2", "w_td", "25", "z_td", "5", "f_t", "ipod")); assertU(adoc("id", "1", "x_td", "0", "y_td", "2", "w_td1", "25", "z_td", "5", "f_t", "ipod"));
assertU(adoc("id", "2", "x_td", "2", "y_td", "2", "w_td", "15", "z_td", "5", "f_t", "ipod ipod ipod ipod ipod")); assertU(adoc("id", "2", "x_td", "2", "y_td", "2", "w_td1", "15", "z_td", "5", "f_t", "ipod ipod ipod ipod ipod"));
assertU(adoc("id", "3", "x_td", "3", "y_td", "2", "w_td", "55", "z_td", "5", "f_t", "ipod ipod ipod ipod ipod ipod ipod ipod ipod")); assertU(adoc("id", "3", "x_td", "3", "y_td", "2", "w_td1", "55", "z_td", "5", "f_t", "ipod ipod ipod ipod ipod ipod ipod ipod ipod"));
assertU(adoc("id", "4", "x_td", "4", "y_td", "2", "w_td", "45", "z_td", "5", "f_t", "ipod ipod ipod ipod ipod ipod ipod")); assertU(adoc("id", "4", "x_td", "4", "y_td", "2", "w_td1", "45", "z_td", "5", "f_t", "ipod ipod ipod ipod ipod ipod ipod"));
assertU(commit()); assertU(commit());
assertQ(req("fl", "*,score", "q", "*:*"), assertQ(req("fl", "*,score", "q", "*:*"),
@ -82,8 +82,8 @@ public class SortByFunctionTest extends AbstractSolrTestCase {
"//result/doc[3]/int[@name='id'][.='3']", "//result/doc[3]/int[@name='id'][.='3']",
"//result/doc[4]/int[@name='id'][.='4']" "//result/doc[4]/int[@name='id'][.='4']"
); );
//the function is equal, w_td separates //the function is equal, w_td1 separates
assertQ(req("q", "*:*", "fl", "id", "sort", "sum(z_td, y_td) asc, w_td asc"), assertQ(req("q", "*:*", "fl", "id", "sort", "sum(z_td, y_td) asc, w_td1 asc"),
"//*[@numFound='4']", "//*[@numFound='4']",
"//result/doc[1]/int[@name='id'][.='2']", "//result/doc[1]/int[@name='id'][.='2']",
"//result/doc[2]/int[@name='id'][.='1']", "//result/doc[2]/int[@name='id'][.='1']",
@ -127,4 +127,4 @@ public class SortByFunctionTest extends AbstractSolrTestCase {
/* /*
<lst name="responseHeader"><int name="status">0</int><int name="QTime">93</int></lst><result name="response" numFound="4" start="0" maxScore="1.0"><doc><float name="score">1.0</float><int name="id">4</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.412Z</date><arr name="x_td"><double>4.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc><doc><float name="score">1.0</float><int name="id">3</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.409Z</date><arr name="x_td"><double>3.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc><doc><float name="score">1.0</float><int name="id">2</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.406Z</date><arr name="x_td"><double>2.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc><doc><float name="score">1.0</float><int name="id">1</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.361Z</date><arr name="x_td"><double>0.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc></result> <lst name="responseHeader"><int name="status">0</int><int name="QTime">93</int></lst><result name="response" numFound="4" start="0" maxScore="1.0"><doc><float name="score">1.0</float><int name="id">4</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.412Z</date><arr name="x_td"><double>4.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc><doc><float name="score">1.0</float><int name="id">3</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.409Z</date><arr name="x_td"><double>3.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc><doc><float name="score">1.0</float><int name="id">2</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.406Z</date><arr name="x_td"><double>2.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc><doc><float name="score">1.0</float><int name="id">1</int><int name="intDefault">42</int><arr name="multiDefault"><str>muLti-Default</str></arr><date name="timestamp">2009-12-12T12:59:46.361Z</date><arr name="x_td"><double>0.0</double></arr><arr name="y_td"><double>2.0</double></arr></doc></result>
*/ */