You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2014/11/08 12:32:23 UTC

svn commit: r1637544 [6/6] - in /lucene/dev/branches/lucene6005: ./ lucene/ lucene/core/ lucene/core/src/java/org/apache/lucene/codecs/perfield/ lucene/core/src/java/org/apache/lucene/document/ lucene/core/src/java/org/apache/lucene/index/ lucene/core/...

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java Sat Nov  8 11:32:18 2014
@@ -20,9 +20,11 @@ package org.apache.solr.handler.componen
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Date;
 import java.util.List;
 
 import org.apache.solr.BaseDistributedSearchTestCase;
+import org.apache.solr.client.solrj.response.FieldStatsInfo;
 import org.apache.solr.client.solrj.response.PivotField;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.params.FacetParams;
@@ -46,20 +48,22 @@ public class DistributedFacetPivotSmallT
     // NOTE: we use the literal (4 character) string "null" as a company name
     // to help ensure there isn't any bugs where the literal string is treated as if it 
     // were a true NULL value.
-    index(id, 19, "place_t", "cardiff dublin", "company_t", "microsoft polecat");
-    index(id, 20, "place_t", "dublin", "company_t", "polecat microsoft null");
+    index(id, 19, "place_t", "cardiff dublin", "company_t", "microsoft polecat", "price_ti", "15");
+    index(id, 20, "place_t", "dublin", "company_t", "polecat microsoft null", "price_ti", "19",
+          // this is the only doc to have solo_* fields, therefore only 1 shard has them
+          // TODO: add enum field - blocked by SOLR-6682
+          "solo_i", 42, "solo_s", "lonely", "solo_dt", "1976-03-06T01:23:45Z");
     index(id, 21, "place_t", "london la dublin", "company_t",
-        "microsoft fujitsu null polecat");
+        "microsoft fujitsu null polecat", "price_ti", "29");
     index(id, 22, "place_t", "krakow london cardiff", "company_t",
-        "polecat null bbc");
-    index(id, 23, "place_t", "london", "company_t", "");
+        "polecat null bbc", "price_ti", "39");
+    index(id, 23, "place_t", "london", "company_t", "", "price_ti", "29");
     index(id, 24, "place_t", "la", "company_t", "");
-    index(id, 25, "company_t", "microsoft polecat null fujitsu null bbc");
+    index(id, 25, "company_t", "microsoft polecat null fujitsu null bbc", "price_ti", "59");
     index(id, 26, "place_t", "krakow", "company_t", "null");
-    index(id, 27, "place_t", "krakow cardiff dublin london la", "company_t",
-        "null microsoft polecat bbc fujitsu");
-    index(id, 28, "place_t", "cork", "company_t",
-        "fujitsu rte");
+    index(id, 27, "place_t", "krakow cardiff dublin london la", 
+          "company_t", "null microsoft polecat bbc fujitsu");
+    index(id, 28, "place_t", "cork", "company_t", "fujitsu rte");
     commit();
     
     handle.clear();
@@ -332,6 +336,76 @@ public class DistributedFacetPivotSmallT
         throw new AssertionError(ae.getMessage() + " <== " + p.toString(), ae);
       }
     }
+
+    doTestDeepPivotStats();
+
+    doTestPivotStatsFromOneShard();
+  }
+
+  private void doTestDeepPivotStats() throws Exception {
+    SolrParams params = params("q", "*:*", "rows", "0", 
+                               "facet", "true", "stats", "true", 
+                               "facet.pivot", "{!stats=s1}place_t,company_t", 
+                               "stats.field", "{!key=avg_price tag=s1}price_ti");
+    QueryResponse rsp = query(params);
+
+    List<PivotField> placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+    PivotField dublinPivotField = placePivots.get(0);
+    assertEquals("dublin", dublinPivotField.getValue());
+    assertEquals(4, dublinPivotField.getCount());
+
+    PivotField microsoftPivotField = dublinPivotField.getPivot().get(0);
+    assertEquals("microsoft", microsoftPivotField.getValue());
+    assertEquals(4, microsoftPivotField.getCount());
+
+    FieldStatsInfo dublinMicrosoftStatsInfo = microsoftPivotField.getFieldStatsInfo().get("avg_price");
+    assertEquals(15.0, dublinMicrosoftStatsInfo.getMin());
+    assertEquals(29.0, dublinMicrosoftStatsInfo.getMax());
+    assertEquals(3, (long) dublinMicrosoftStatsInfo.getCount());
+    assertEquals(1, (long) dublinMicrosoftStatsInfo.getMissing());
+    assertEquals(63.0, dublinMicrosoftStatsInfo.getSum());
+    assertEquals(1427.0, dublinMicrosoftStatsInfo.getSumOfSquares(), 0.1E-7);
+    assertEquals(21.0, (double) dublinMicrosoftStatsInfo.getMean(), 0.1E-7);
+    assertEquals(7.211102550927978, dublinMicrosoftStatsInfo.getStddev(), 0.1E-7);
+
+
+    PivotField cardiffPivotField = placePivots.get(2);
+    assertEquals("cardiff", cardiffPivotField.getValue());
+    assertEquals(3, cardiffPivotField.getCount());
+
+    PivotField polecatPivotField = cardiffPivotField.getPivot().get(0);
+    assertEquals("polecat", polecatPivotField.getValue());
+    assertEquals(3, polecatPivotField.getCount());
+
+    FieldStatsInfo cardiffPolecatStatsInfo = polecatPivotField.getFieldStatsInfo().get("avg_price");
+    assertEquals(15.0, cardiffPolecatStatsInfo.getMin());
+    assertEquals(39.0, cardiffPolecatStatsInfo.getMax());
+    assertEquals(2, (long) cardiffPolecatStatsInfo.getCount());
+    assertEquals(1, (long) cardiffPolecatStatsInfo.getMissing());
+    assertEquals(54.0, cardiffPolecatStatsInfo.getSum());
+    assertEquals(1746.0, cardiffPolecatStatsInfo.getSumOfSquares(), 0.1E-7);
+    assertEquals(27.0, (double) cardiffPolecatStatsInfo.getMean(), 0.1E-7);
+    assertEquals(16.97056274847714, cardiffPolecatStatsInfo.getStddev(), 0.1E-7);
+
+
+    PivotField krakowPivotField = placePivots.get(3);
+    assertEquals("krakow", krakowPivotField.getValue());
+    assertEquals(3, krakowPivotField.getCount());
+
+    PivotField fujitsuPivotField = krakowPivotField.getPivot().get(3);
+    assertEquals("fujitsu", fujitsuPivotField.getValue());
+    assertEquals(1, fujitsuPivotField.getCount());
+
+    FieldStatsInfo krakowFujitsuStatsInfo = fujitsuPivotField.getFieldStatsInfo().get("avg_price");
+    assertEquals(null, krakowFujitsuStatsInfo.getMin());
+    assertEquals(null, krakowFujitsuStatsInfo.getMax());
+    assertEquals(0, (long) krakowFujitsuStatsInfo.getCount());
+    assertEquals(1, (long) krakowFujitsuStatsInfo.getMissing());
+    assertEquals(0.0, krakowFujitsuStatsInfo.getSum());
+    assertEquals(0.0, krakowFujitsuStatsInfo.getSumOfSquares(), 0.1E-7);
+    assertEquals(Double.NaN, (double) krakowFujitsuStatsInfo.getMean(), 0.1E-7);
+    assertEquals(0.0, krakowFujitsuStatsInfo.getStddev(), 0.1E-7);
   }
 
   // Useful to check for errors, orders lists and does toString() equality check
@@ -351,6 +425,46 @@ public class DistributedFacetPivotSmallT
     }
     assertEquals(expectedPlacePivots.toString(), placePivots.toString());
   }
+
+  /**
+   * sanity check the stat values nested under a pivot when at least one shard
+   * has nothing but missing values for the stat
+   */
+  private void doTestPivotStatsFromOneShard() throws Exception {
+    SolrParams params = params("q", "*:*", "rows", "0", 
+                               "facet", "true", "stats", "true", 
+                               "facet.pivot", "{!stats=s1}place_t,company_t", 
+                               "stats.field", "{!tag=s1}solo_i",
+                               "stats.field", "{!tag=s1}solo_s",
+                               "stats.field", "{!tag=s1}solo_dt");
+                               
+    QueryResponse rsp = query(params);
+
+    List<PivotField> placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+    PivotField placePivot = placePivots.get(0);
+    assertEquals("dublin", placePivot.getValue());
+    assertEquals(4, placePivot.getCount());
+
+    PivotField companyPivot = placePivot.getPivot().get(2);
+    assertEquals("null", companyPivot.getValue());
+    assertEquals(3, companyPivot.getCount());
+
+    for (PivotField pf : new PivotField[] { placePivot, companyPivot }) {
+      assertThereCanBeOnlyOne(pf, pf.getFieldStatsInfo().get("solo_s"), "lonely");
+
+      assertThereCanBeOnlyOne(pf, pf.getFieldStatsInfo().get("solo_i"), 42.0D);
+      assertEquals(pf.getField()+":"+pf.getValue()+": int mean",
+                   42.0D, pf.getFieldStatsInfo().get("solo_i").getMean());
+
+      Object expected = new Date(194923425000L); // 1976-03-06T01:23:45Z
+      assertThereCanBeOnlyOne(pf, pf.getFieldStatsInfo().get("solo_dt"), expected);
+      assertEquals(pf.getField()+":"+pf.getValue()+": date mean",
+                   expected, pf.getFieldStatsInfo().get("solo_dt").getMean());
+
+      // TODO: add enum field asserts - blocked by SOLR-6682
+    }
+  }
   
   private void testCountSorting(List<PivotField> pivots) {
     Integer lastCount = null;
@@ -365,12 +479,27 @@ public class DistributedFacetPivotSmallT
     }
   }
   
+  /**
+   * given a PivotField, a FieldStatsInfo, and a value; asserts that:
+   * <ul>
+   *  <li>stat count == 1</li>
+   *  <li>stat missing == pivot count - 1</li>
+   *  <li>stat min == stat max == value</li>
+   * </ul>
+   */
+  private void assertThereCanBeOnlyOne(PivotField pf, FieldStatsInfo stats, Object val) {
+    String msg = pf.getField() + ":" + pf.getValue();
+    assertEquals(msg + " stats count", 1L, (long) stats.getCount());
+    assertEquals(msg + " stats missing", pf.getCount()-1L, (long) stats.getMissing());
+    assertEquals(msg + " stats min", val, stats.getMin());
+    assertEquals(msg + " stats max", val, stats.getMax());
+  }
+
   public static class ComparablePivotField extends PivotField {
     
 
-    public ComparablePivotField(String f, Object v, int count,
-        List<PivotField> pivot) {
-      super(f,v,count,pivot);
+    public ComparablePivotField(String f, Object v, int count, List<PivotField> pivot) {
+      super(f,v,count,pivot, null);
     }
 
     @Override

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/response/TestSortingResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/response/TestSortingResponseWriter.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/response/TestSortingResponseWriter.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/response/TestSortingResponseWriter.java Sat Nov  8 11:32:18 2014
@@ -19,7 +19,9 @@ package org.apache.solr.response;
 
 import org.apache.solr.SolrTestCaseJ4;
 import org.junit.*;
+import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
 
+@SuppressCodecs({"Lucene3x", "Lucene40","Lucene41","Lucene42","Lucene45"})
 public class TestSortingResponseWriter extends SolrTestCaseJ4 {
   @BeforeClass
   public static void beforeClass() throws Exception {
@@ -88,63 +90,57 @@ public class TestSortingResponseWriter e
 
     //Test single value DocValue output
     String s =  h.query(req("q", "id:1", "qt", "/export", "fl", "floatdv,intdv,stringdv,longdv,doubledv", "sort", "intdv asc"));
-    assertEquals(s, "{\"numFound\":1, \"docs\":[{\"floatdv\":2.1,\"intdv\":1,\"stringdv\":\"hello world\",\"longdv\":323223232323,\"doubledv\":2344.345}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":1, \"docs\":[{\"floatdv\":2.1,\"intdv\":1,\"stringdv\":\"hello world\",\"longdv\":323223232323,\"doubledv\":2344.345}]}}");
 
     //Test null value string:
     s =  h.query(req("q", "id:7", "qt", "/export", "fl", "floatdv,intdv,stringdv,longdv,doubledv", "sort", "intdv asc"));
-    assertEquals(s, "{\"numFound\":1, \"docs\":[{\"floatdv\":2.1,\"intdv\":7,\"stringdv\":\"\",\"longdv\":323223232323,\"doubledv\":2344.345}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":1, \"docs\":[{\"floatdv\":2.1,\"intdv\":7,\"stringdv\":\"\",\"longdv\":323223232323,\"doubledv\":2344.345}]}}");
 
     //Test multiValue docValues output
     s =  h.query(req("q", "id:1", "qt", "/export", "fl", "intdv_m,floatdv_m,doubledv_m,longdv_m,stringdv_m", "sort", "intdv asc"));
-    assertEquals(s, "{\"numFound\":1, \"docs\":[{\"intdv_m\":[100,250],\"floatdv_m\":[123.321,345.123],\"doubledv_m\":[3444.222,23232.2],\"longdv_m\":[343332,43434343434],\"stringdv_m\":[\"Everton\",\"liverpool\",\"manchester city\"]}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":1, \"docs\":[{\"intdv_m\":[100,250],\"floatdv_m\":[123.321,345.123],\"doubledv_m\":[3444.222,23232.2],\"longdv_m\":[343332,43434343434],\"stringdv_m\":[\"Everton\",\"liverpool\",\"manchester city\"]}]}}");
 
     //Test multiValues docValues output with nulls
     s =  h.query(req("q", "id:7", "qt", "/export", "fl", "intdv_m,floatdv_m,doubledv_m,longdv_m,stringdv_m", "sort", "intdv asc"));
-    assertEquals(s, "{\"numFound\":1, \"docs\":[{\"intdv_m\":[],\"floatdv_m\":[123.321,345.123],\"doubledv_m\":[3444.222,23232.2],\"longdv_m\":[343332,43434343434],\"stringdv_m\":[]}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":1, \"docs\":[{\"intdv_m\":[],\"floatdv_m\":[123.321,345.123],\"doubledv_m\":[3444.222,23232.2],\"longdv_m\":[343332,43434343434],\"stringdv_m\":[]}]}}");
 
     //Test single sort param is working
     s =  h.query(req("q", "id:(1 2)", "qt", "/export", "fl", "intdv", "sort", "intdv desc"));
-    assertEquals(s, "{\"numFound\":2, \"docs\":[{\"intdv\":2},{\"intdv\":1}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":2, \"docs\":[{\"intdv\":2},{\"intdv\":1}]}}");
 
     s =  h.query(req("q", "id:(1 2)", "qt", "/export", "fl", "intdv", "sort", "intdv asc"));
-    assertEquals(s, "{\"numFound\":2, \"docs\":[{\"intdv\":1},{\"intdv\":2}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":2, \"docs\":[{\"intdv\":1},{\"intdv\":2}]}}");
 
     // Test sort on String will null value. Null value should sort last on desc and first on asc.
 
     s =  h.query(req("q", "id:(1 7)", "qt", "/export", "fl", "intdv", "sort", "stringdv desc"));
-    assertEquals(s, "{\"numFound\":2, \"docs\":[{\"intdv\":1},{\"intdv\":7}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":2, \"docs\":[{\"intdv\":1},{\"intdv\":7}]}}");
 
     s =  h.query(req("q", "id:(1 7)", "qt", "/export", "fl", "intdv", "sort", "stringdv asc"));
-    assertEquals(s, "{\"numFound\":2, \"docs\":[{\"intdv\":7},{\"intdv\":1}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":2, \"docs\":[{\"intdv\":7},{\"intdv\":1}]}}");
 
 
     //Test multi-sort params
     s =  h.query(req("q", "id:(1 2)", "qt", "/export", "fl", "intdv", "sort", "floatdv asc,intdv desc"));
-    assertEquals(s, "{\"numFound\":2, \"docs\":[{\"intdv\":2},{\"intdv\":1}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":2, \"docs\":[{\"intdv\":2},{\"intdv\":1}]}}");
 
     s =  h.query(req("q", "id:(1 2)", "qt", "/export", "fl", "intdv", "sort", "floatdv desc,intdv asc"));
-    assertEquals(s, "{\"numFound\":2, \"docs\":[{\"intdv\":1},{\"intdv\":2}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":2, \"docs\":[{\"intdv\":1},{\"intdv\":2}]}}");
 
     //Test three sort fields
     s =  h.query(req("q", "id:(1 2 3)", "qt", "/export", "fl", "intdv", "sort", "floatdv asc,stringdv asc,intdv desc"));
-    assertEquals(s, "{\"numFound\":3, \"docs\":[{\"intdv\":3},{\"intdv\":2},{\"intdv\":1}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":3, \"docs\":[{\"intdv\":3},{\"intdv\":2},{\"intdv\":1}]}}");
 
     //Test three sort fields
     s =  h.query(req("q", "id:(1 2 3)", "qt", "/export", "fl", "intdv", "sort", "floatdv asc,stringdv desc,intdv asc"));
-    assertEquals(s, "{\"numFound\":3, \"docs\":[{\"intdv\":1},{\"intdv\":2},{\"intdv\":3}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":3, \"docs\":[{\"intdv\":1},{\"intdv\":2},{\"intdv\":3}]}}");
 
     //Test four sort fields
     s =  h.query(req("q", "id:(1 2 3)", "qt", "/export", "fl", "intdv", "sort", "floatdv asc,floatdv desc,floatdv asc,intdv desc"));
-    assertEquals(s, "{\"numFound\":3, \"docs\":[{\"intdv\":3},{\"intdv\":2},{\"intdv\":1}]}");
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":3, \"docs\":[{\"intdv\":3},{\"intdv\":2},{\"intdv\":1}]}}");
 
     s =  h.query(req("q", "id:(1 2 3)", "qt", "/export", "fl", "intdv", "sort", "doubledv desc"));
-    assertEquals(s, "{\"numFound\":3, \"docs\":[{\"intdv\":3},{\"intdv\":1},{\"intdv\":2}]}");
-
-    s =  h.query(req("q", "id:100000", "qt", "/export", "fl", "intdv", "sort", "doubledv desc"));
-    assertEquals(s, "{\"numFound\":0, \"docs\":[]}");
-
-
-
+    assertEquals(s, "{\"responseHeader\": {\"status\": 0}, \"response\":{\"numFound\":3, \"docs\":[{\"intdv\":3},{\"intdv\":1},{\"intdv\":2}]}}");
 
   }
 }

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/TestRestManager.java Sat Nov  8 11:32:18 2014
@@ -26,6 +26,7 @@ import org.apache.solr.common.util.Named
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.rest.ManagedResourceStorage.StorageIO;
 import org.apache.solr.rest.schema.analysis.ManagedWordSetResource;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.noggit.JSONUtil;
 import org.restlet.Request;
@@ -74,6 +75,7 @@ public class TestRestManager extends Sol
    * Test RestManager initialization and handling of registered ManagedResources. 
    */
   @Test
+  @Ignore
   public void testManagedResourceRegistrationAndInitialization() throws Exception {
     // first, we need to register some ManagedResources, which is done with the registry
     // provided by the SolrResourceLoader
@@ -178,7 +180,7 @@ public class TestRestManager extends Sol
     */
     
     // no pre-existing managed config components
-    assertJQ("/config/managed", "/managedResources==[]");
+//    assertJQ("/config/managed", "/managedResources==[]");
         
     // add a ManagedWordSetResource for managing protected words (for stemming)
     String newEndpoint = "/schema/analysis/protwords/english";
@@ -223,7 +225,7 @@ public class TestRestManager extends Sol
     assertJDelete(newEndpoint, "/responseHeader/status==0");
 
     // make sure it's really gone
-    assertJQ("/config/managed", "/managedResources==[]");
+//    assertJQ("/config/managed", "/managedResources==[]");
   }
   
   @Test

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java Sat Nov  8 11:32:18 2014
@@ -215,7 +215,11 @@ public class TestBulkSchemaAPI extends R
   }
 
   public static Map getRespMap(RestTestHarness restHarness) throws Exception {
-    String response = restHarness.query("/schema?wt=json");
+    return getAsMap("/schema?wt=json", restHarness);
+  }
+
+  public static Map getAsMap(String uri, RestTestHarness restHarness) throws Exception {
+    String response = restHarness.query(uri);
     return (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
   }
 

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/IndexSchemaTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/IndexSchemaTest.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/IndexSchemaTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/IndexSchemaTest.java Sat Nov  8 11:32:18 2014
@@ -92,5 +92,20 @@ public class IndexSchemaTest extends Sol
     SolrCore core = h.getCore();
     IndexSchema schema = core.getLatestSchema();
     assertFalse(schema.getField("id").multiValued());
+    
+    // Test TrieDate fields. The following asserts are expecting a field type defined as:
+    String expectedDefinition = "<fieldtype name=\"tdatedv\" class=\"solr.TrieDateField\" " +
+        "precisionStep=\"6\" docValues=\"true\" multiValued=\"true\"/>";
+    FieldType tdatedv = schema.getFieldType("foo_tdtdv");
+    assertTrue("Expecting a field type defined as " + expectedDefinition, 
+        tdatedv instanceof TrieDateField);
+    assertTrue("Expecting a field type defined as " + expectedDefinition,
+        tdatedv.hasProperty(FieldProperties.DOC_VALUES));
+    assertTrue("Expecting a field type defined as " + expectedDefinition,
+        tdatedv.isMultiValued());
+    assertEquals("Expecting a field type defined as " + expectedDefinition,
+        6, ((TrieDateField)tdatedv).getPrecisionStep());
   }
+  
+  
 }

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java Sat Nov  8 11:32:18 2014
@@ -24,6 +24,7 @@ import org.junit.Test;
 
 import java.io.File;
 import java.util.HashMap;
+import java.util.Map;
 import java.util.TimeZone;
 
 /**
@@ -153,4 +154,22 @@ public class PrimitiveFieldTypeTest exte
     bin.init(schema, initMap);
     assertFalse(bin.hasProperty(FieldType.OMIT_NORMS));
   }
+  
+  public void testTrieDateField() {
+    schema = IndexSchemaFactory.buildIndexSchema(testConfHome + "schema15.xml", config);
+    TrieDateField tdt = new TrieDateField();
+    Map<String, String> args = new HashMap<>();
+    args.put("sortMissingLast", "true");
+    args.put("indexed", "true");
+    args.put("stored", "false");
+    args.put("docValues", "true");
+    args.put("precisionStep", "16");
+    tdt.setArgs(schema, args);
+    assertTrue(tdt.hasProperty(FieldType.OMIT_NORMS));
+    assertTrue(tdt.hasProperty(FieldType.SORT_MISSING_LAST));
+    assertTrue(tdt.hasProperty(FieldType.INDEXED));
+    assertFalse(tdt.hasProperty(FieldType.STORED));
+    assertTrue(tdt.hasProperty(FieldType.DOC_VALUES));
+    assertEquals(16, tdt.getPrecisionStep());
+  }
 }

Modified: lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java (original)
+++ lucene/dev/branches/lucene6005/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java Sat Nov  8 11:32:18 2014
@@ -129,6 +129,20 @@ public class CloudMLTQParserTest extends
           compareParsedQueryStrings(expectedQueryString,
           actualParsedQueries.get(counter)));
     }
+
+    // Assert that {!mlt}id does not throw an exception i.e. implicitly, only fields that are stored + have explicit
+    // analyzer are used for MLT Query construction.
+    params = new ModifiableSolrParams();
+    params.set(CommonParams.Q, "{!mlt}20");
+
+    queryResponse = queryServer(params);
+    solrDocuments = queryResponse.getResults();
+    expectedIds = new int[]{18, 23, 13, 14, 20, 22, 19, 21, 15, 16};
+    i = 0;
+    for (SolrDocument solrDocument : solrDocuments) {
+      actualIds[i++] =  Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+    }
+    assertArrayEquals(expectedIds, actualIds);
   }
   
   private boolean compareParsedQueryStrings(String expected, String actual) {

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java Sat Nov  8 11:32:18 2014
@@ -806,6 +806,13 @@ public class SolrQuery extends Modifiabl
     this.add( StatsParams.STATS_FIELD, field );
   }
   
+
+  public void addGetFieldStatistics( String ... field )
+    {
+      this.set( StatsParams.STATS, true );
+      this.add( StatsParams.STATS_FIELD, field );
+    }
+  
   public void addStatsFieldFacets( String field, String ... facets )
   {
     if( field == null ) {

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java Sat Nov  8 11:32:18 2014
@@ -180,6 +180,10 @@ public class FieldStatsInfo implements S
     return stddev;
   }
 
+  public Double getSumOfSquares() {
+    return sumOfSquares;
+  }
+
   public Map<String, List<FieldStatsInfo>> getFacets() {
     return facets;
   }

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java Sat Nov  8 11:32:18 2014
@@ -20,6 +20,7 @@ package org.apache.solr.client.solrj.res
 import java.io.PrintStream;
 import java.io.Serializable;
 import java.util.List;
+import java.util.Map;
 
 public class PivotField implements Serializable
 {
@@ -27,13 +28,23 @@ public class PivotField implements Seria
   final Object  _value;
   final int     _count;
   final List<PivotField> _pivot;
-   
-  public PivotField( String f, Object v, int count, List<PivotField> pivot )
+  final Map<String,FieldStatsInfo> _statsInfo;
+
+  /**
+   * @deprecated Use {@link #PivotField(String,Object,int,List,Map)} with a null <code>statsInfo</code>
+   */
+  @Deprecated
+  public PivotField( String f, Object v, int count, List<PivotField> pivot) {
+    this(f, v, count, pivot, null);
+  }
+
+  public PivotField( String f, Object v, int count, List<PivotField> pivot, Map<String,FieldStatsInfo> statsInfo)
   {
     _field = f;
     _value = v;
     _count = count;
     _pivot = pivot;
+    _statsInfo = statsInfo;
   }
    
   public String getField() {
@@ -52,6 +63,10 @@ public class PivotField implements Seria
     return _pivot;
   }
    
+  public Map<String,FieldStatsInfo> getFieldStatsInfo() {
+    return _statsInfo;
+  }
+
   @Override
   public String toString()
   {
@@ -63,7 +78,16 @@ public class PivotField implements Seria
     for( int i=0; i<indent; i++ ) {
       out.print( "  " );
     }
-    out.println( _field + "=" + _value + " ("+_count+")" );
+    out.print( _field + "=" + _value + " ("+_count+")" );
+    if (null != _statsInfo) {
+      out.print( "->stats:[" ); 
+      for( FieldStatsInfo fieldStatsInfo : _statsInfo.values() ) {
+        out.print(fieldStatsInfo.toString());
+        out.print(",");
+      }
+      out.print("]");
+    }
+    out.println();
     if( _pivot != null ) {
       for( PivotField p : _pivot ) {
         p.write( out, indent+1 );

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java Sat Nov  8 11:32:18 2014
@@ -23,6 +23,7 @@ import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
@@ -163,19 +164,25 @@ public class QueryResponse extends SolrR
   }
   
   private void extractStatsInfo(NamedList<Object> info) {
+    _fieldStatsInfo = extractFieldStatsInfo(info);
+  }
+
+  private Map<String, FieldStatsInfo> extractFieldStatsInfo(NamedList<Object> info) {
     if( info != null ) {
-      _fieldStatsInfo = new HashMap<>();
+       Map<String, FieldStatsInfo> fieldStatsInfoMap = new TreeMap<>();
       NamedList<NamedList<Object>> ff = (NamedList<NamedList<Object>>) info.get( "stats_fields" );
       if( ff != null ) {
         for( Map.Entry<String,NamedList<Object>> entry : ff ) {
           NamedList<Object> v = entry.getValue();
           if( v != null ) {
-            _fieldStatsInfo.put( entry.getKey(), 
+             fieldStatsInfoMap.put( entry.getKey(),
                 new FieldStatsInfo( v, entry.getKey() ) );
           }
         }
       }
+       return fieldStatsInfoMap;
     }
+    return null;
   }
 
   private void extractDebugInfo( NamedList<Object> debug )
@@ -396,14 +403,38 @@ public class QueryResponse extends SolrR
       Object v = nl.getVal( 1 );
       assert "count".equals(nl.getName(2));
       int cnt = ((Integer)nl.getVal( 2 )).intValue();
-      List<PivotField> p = null;
+
+      List<PivotField> subPivots = null;
+      Map<String,FieldStatsInfo> fieldStatsInfos = null;
+
       if (4 <= nl.size()) {
-        assert "pivot".equals(nl.getName(3));
-        Object subPiv = nl.getVal(3);
-        assert null != subPiv : "Server sent back 'null' for sub pivots?";
-        p = readPivots( (List<NamedList>) subPiv );
+        for(int index = 3; index < nl.size(); index++) {
+          final String key = nl.getName(index);
+          final Object val = nl.getVal(index);
+          switch (key) {
+
+          case "pivot": {
+            assert null != val : "Server sent back 'null' for sub pivots?";
+            assert val instanceof List : "Server sent non-List for sub pivots?";
+
+            subPivots = readPivots( (List<NamedList>) val );
+            break;
+          }
+          case "stats": {
+            assert null != val : "Server sent back 'null' for stats?";
+            assert val instanceof NamedList : "Server sent non-NamedList for stats?";
+
+            fieldStatsInfos = extractFieldStatsInfo((NamedList<Object>) val);
+            break;
+          }
+          default: 
+            throw new RuntimeException( "unknown key in pivot: "+ key+ " ["+val+"]");
+
+          }
+        }
       }
-      values.add( new PivotField( f, v, cnt, p ) );
+
+      values.add( new PivotField( f, v, cnt, subPivots, fieldStatsInfos ) );
     }
     return values;
   }

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java Sat Nov  8 11:32:18 2014
@@ -41,6 +41,7 @@ import org.apache.solr.common.StringUtil
 import org.apache.solr.common.cloud.ZkClientConnectionStrategy.ZkUpdate;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.SolrjNamedThreadFactory;
+import org.apache.zookeeper.AsyncCallback;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.KeeperException.NoNodeException;

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/params/CollectionParams.java Sat Nov  8 11:32:18 2014
@@ -49,7 +49,7 @@ public interface CollectionParams 
     CLUSTERSTATUS,
     ADDREPLICAPROP,
     DELETEREPLICAPROP,
-    BALANCESLICEUNIQUE,
+    BALANCESHARDUNIQUE,
     REBALANCELEADERS;
     
     public static CollectionAction get( String p )

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java Sat Nov  8 11:32:18 2014
@@ -394,6 +394,7 @@ public class JsonRecordReader {
             event = parser.nextEvent();
             if (event == STRING ||
                 event == LONG ||
+                event == NUMBER ||
                 event == BIGNUMBER ||
                 event == BOOLEAN ||
                 event == NULL) {

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java Sat Nov  8 11:32:18 2014
@@ -57,12 +57,9 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
-import java.util.Set;
 
 /**
  * This should include tests against the example solr config
@@ -814,6 +811,197 @@ abstract public class SolrExampleTests e
     doPivotFacetTest(false);
   }
     
+  @Test
+  public void testPivotFacetsStats() throws Exception {
+    SolrServer server = getSolrServer();
+
+    // Empty the database...
+    server.deleteByQuery("*:*");// delete everything!
+    server.commit();
+    assertNumFound("*:*", 0); // make sure it got in
+
+    int id = 1;
+    ArrayList<SolrInputDocument> docs = new ArrayList<>();
+    docs.add(makeTestDoc("id", id++, "features", "aaa", "manu", "apple", "cat", "a", "inStock", true, "popularity", 12, "price", .017));
+    docs.add(makeTestDoc("id", id++, "features", "aaa", "manu", "lg", "cat", "a", "inStock", false, "popularity", 13, "price", 16.04));
+    docs.add(makeTestDoc("id", id++, "features", "aaa", "manu", "samsung", "cat", "a", "inStock", true, "popularity", 14, "price", 12.34));
+    docs.add(makeTestDoc("id", id++, "features", "aaa", "manu", "lg", "cat", "b", "inStock", false, "popularity", 24, "price", 51.39));
+    docs.add(makeTestDoc("id", id++, "features", "aaa", "manu", "nokia", "cat", "b", "inStock", true, "popularity", 28, "price", 131.39));
+    docs.add(makeTestDoc("id", id++, "features", "bbb", "manu", "ztc", "cat", "a", "inStock", false, "popularity", 32));
+    docs.add(makeTestDoc("id", id++, "features", "bbb", "manu", "htc", "cat", "a", "inStock", true, "popularity", 31, "price", 131.39));
+    docs.add(makeTestDoc("id", id++, "features", "bbb", "manu", "apple", "cat", "b", "inStock", false, "popularity", 36));
+    docs.add(makeTestDoc("id", id++, "features", "bbb", "manu", "lg", "cat", "b", "inStock", true, "popularity", 37, "price", 1.39));
+    docs.add(makeTestDoc("id", id++, "features", "bbb", "manu", "ztc", "cat", "b", "inStock", false, "popularity", 38, "price", 47.98));
+    docs.add(makeTestDoc("id", id++, "features", "bbb", "manu", "ztc", "cat", "b", "inStock", true, "popularity", -38));
+    docs.add(makeTestDoc("id", id++, "cat", "b")); // something not matching all fields
+    server.add(docs);
+    server.commit();
+
+    for (String pivot : new String[] { "{!key=pivot_key stats=s1}features,manu",
+                                       "{!key=pivot_key stats=s1}features,manu,cat",
+                                       "{!key=pivot_key stats=s1}features,manu,cat,inStock"
+      }) {
+
+      // for any of these pivot params, the assertions we check should be teh same
+      // (we stop asserting at the "manu" level)
+      
+      SolrQuery query = new SolrQuery("*:*");
+      query.addFacetPivotField(pivot);
+      query.setFacetLimit(1);
+      query.addGetFieldStatistics("{!key=foo_price tag=s1}price", "{!tag=s1}popularity");
+      query.setFacetMinCount(0);
+      query.setRows(0);
+
+      QueryResponse rsp = server.query(query);
+
+      // check top (ie: non-pivot) stats
+      Map<String, FieldStatsInfo> map = rsp.getFieldStatsInfo();
+      FieldStatsInfo intValueStatsInfo = map.get("popularity");
+      assertEquals(-38.0d, intValueStatsInfo.getMin());
+      assertEquals(38.0d, intValueStatsInfo.getMax());
+      assertEquals(11l, intValueStatsInfo.getCount().longValue());
+      assertEquals(1l, intValueStatsInfo.getMissing().longValue());
+      assertEquals(227.0d, intValueStatsInfo.getSum());
+      assertEquals(20.636363636363637d, intValueStatsInfo.getMean());
+      
+      FieldStatsInfo doubleValueStatsInfo = map.get("foo_price");
+      assertEquals(.017d, (double) doubleValueStatsInfo.getMin(), .01d);
+      assertEquals(131.39d, (double) doubleValueStatsInfo.getMax(), .01d);
+      assertEquals(8l, doubleValueStatsInfo.getCount().longValue());
+      assertEquals(4l, doubleValueStatsInfo.getMissing().longValue());
+      assertEquals(391.93d, (double) doubleValueStatsInfo.getSum(), .01d);
+      assertEquals(48.99d, (double) doubleValueStatsInfo.getMean(), .01d);
+
+      // now get deeper and look at the pivots...
+
+      NamedList<List<PivotField>> pivots = rsp.getFacetPivot();
+      assertTrue( ! pivots.get("pivot_key").isEmpty() );
+
+      List<PivotField> list = pivots.get("pivot_key");
+      PivotField featuresBBBPivot = list.get(0);
+      assertEquals("features", featuresBBBPivot.getField());
+      assertEquals("bbb", featuresBBBPivot.getValue());
+      assertNotNull(featuresBBBPivot.getFieldStatsInfo());
+      assertEquals(2, featuresBBBPivot.getFieldStatsInfo().size());
+      
+      FieldStatsInfo featuresBBBPivotStats1 = featuresBBBPivot.getFieldStatsInfo().get("foo_price");
+      assertEquals("foo_price", featuresBBBPivotStats1.getName());
+      assertEquals(131.39d, (double) featuresBBBPivotStats1.getMax(), .01d);
+      assertEquals(1.38d, (double) featuresBBBPivotStats1.getMin(), .01d);
+      assertEquals(180.75d, (double) featuresBBBPivotStats1.getSum(), .01d);
+      assertEquals(3, (long) featuresBBBPivotStats1.getCount());
+      assertEquals(3, (long) featuresBBBPivotStats1.getMissing());
+      assertEquals(60.25d, (double) featuresBBBPivotStats1.getMean(), .01d);
+      assertEquals(65.86d, featuresBBBPivotStats1.getStddev(), .01d);
+      assertEquals(19567.34d, featuresBBBPivotStats1.getSumOfSquares(), .01d);
+      
+      FieldStatsInfo featuresBBBPivotStats2 = featuresBBBPivot.getFieldStatsInfo().get("popularity");
+      assertEquals("popularity", featuresBBBPivotStats2.getName());
+      assertEquals(38.0d, (double) featuresBBBPivotStats2.getMax(), .01d);
+      assertEquals(-38.0d, (double) featuresBBBPivotStats2.getMin(), .01d);
+      assertEquals(136.0d, (double) featuresBBBPivotStats2.getSum(), .01d);
+      assertEquals(6, (long) featuresBBBPivotStats2.getCount());
+      assertEquals(0, (long) featuresBBBPivotStats2.getMissing());
+      assertEquals(22.66d, (double) featuresBBBPivotStats2.getMean(), .01d);
+      assertEquals(29.85d, featuresBBBPivotStats2.getStddev(), .01d);
+      assertEquals(7538.0d, featuresBBBPivotStats2.getSumOfSquares(), .01d);
+      
+      List<PivotField> nestedPivotList = featuresBBBPivot.getPivot();
+      PivotField featuresBBBPivotPivot = nestedPivotList.get(0);
+      assertEquals("manu", featuresBBBPivotPivot.getField());
+      assertEquals("ztc", featuresBBBPivotPivot.getValue());
+      assertNotNull(featuresBBBPivotPivot.getFieldStatsInfo());
+      assertEquals(2, featuresBBBPivotPivot.getFieldStatsInfo().size());
+      
+      FieldStatsInfo featuresBBBManuZtcPivotStats1 = featuresBBBPivotPivot.getFieldStatsInfo().get("foo_price");
+      assertEquals("foo_price", featuresBBBManuZtcPivotStats1.getName());
+      assertEquals(47.97d, (double) featuresBBBManuZtcPivotStats1.getMax(), .01d);
+      assertEquals(47.97d, (double) featuresBBBManuZtcPivotStats1.getMin(), .01d);
+      assertEquals(47.97d, (double) featuresBBBManuZtcPivotStats1.getSum(), .01d);
+      assertEquals(1, (long) featuresBBBManuZtcPivotStats1.getCount());
+      assertEquals(2, (long) featuresBBBManuZtcPivotStats1.getMissing());
+      assertEquals(47.97d, (double) featuresBBBManuZtcPivotStats1.getMean(), .01d);
+      assertEquals(0.0d, featuresBBBManuZtcPivotStats1.getStddev(), .01d);
+      assertEquals(2302.08d, featuresBBBManuZtcPivotStats1.getSumOfSquares(), .01d);
+      
+      
+      FieldStatsInfo featuresBBBManuZtcPivotStats2 = featuresBBBPivotPivot.getFieldStatsInfo().get("popularity");
+      assertEquals("popularity", featuresBBBManuZtcPivotStats2.getName());
+      assertEquals(38.0d, (double) featuresBBBManuZtcPivotStats2.getMax(), .01d);
+      assertEquals(-38.0d, (double) featuresBBBManuZtcPivotStats2.getMin(), .01d);
+      assertEquals(32.0, (double) featuresBBBManuZtcPivotStats2.getSum(), .01d);
+      assertEquals(3, (long) featuresBBBManuZtcPivotStats2.getCount());
+      assertEquals(0, (long) featuresBBBManuZtcPivotStats2.getMissing());
+      assertEquals(10.66d, (double) featuresBBBManuZtcPivotStats2.getMean(), .01d);
+      assertEquals(42.25d, featuresBBBManuZtcPivotStats2.getStddev(), .01d);
+      assertEquals(3912.0d, featuresBBBManuZtcPivotStats2.getSumOfSquares(), .01d);
+    }
+  }
+
+  @Test
+  public void testPivotFacetsStatsNotSupported() throws Exception {
+    SolrServer server = getSolrServer();
+
+    // Empty the database...
+    server.deleteByQuery("*:*");// delete everything!
+    server.commit();
+    assertNumFound("*:*", 0); // make sure it got in
+
+    // results of this test should be the same regardless of wether any docs in index
+    if (random().nextBoolean()) {
+      server.add(makeTestDoc("id", 1, "features", "aaa", "cat", "a", "inStock", true, "popularity", 12, "price", .017));
+      server.commit();
+    }
+
+    ignoreException("is not currently supported");
+
+    // boolean field
+    SolrQuery query = new SolrQuery("*:*");
+    query.addFacetPivotField("{!stats=s1}features,manu");
+    query.addGetFieldStatistics("{!key=inStock_val tag=s1}inStock");
+    try {
+      server.query(query);
+      fail("SolrException should be thrown on query");
+    } catch (SolrException e) {
+      assertEquals("Pivot facet on boolean is not currently supported, bad request returned", 400, e.code());
+      assertTrue(e.getMessage().contains("is not currently supported"));
+      assertTrue(e.getMessage().contains("boolean"));
+    }
+
+    // asking for multiple stat tags -- see SOLR-6663
+    query = new SolrQuery("*:*");
+    query.addFacetPivotField("{!stats=tag1,tag2}features,manu");
+    query.addGetFieldStatistics("{!tag=tag1}price", "{!tag=tag2}popularity");
+    query.setFacetMinCount(0);
+    query.setRows(0);
+    try {
+      server.query(query);
+      fail("SolrException should be thrown on query");
+    } catch (SolrException e) {
+      assertEquals(400, e.code());
+      assertTrue(e.getMessage().contains("stats"));
+      assertTrue(e.getMessage().contains("comma"));
+      assertTrue(e.getMessage().contains("tag"));
+    }
+
+    // text field
+    query = new SolrQuery("*:*");
+    query.addFacetPivotField("{!stats=s1}features,manu");
+    query.addGetFieldStatistics("{!tag=s1}features");
+    query.setFacetMinCount(0);
+    query.setRows(0);
+    try {
+      server.query(query);
+      fail("SolrException should be thrown on query");
+    } catch (SolrException e) {
+      assertEquals("Pivot facet on string is not currently supported, bad request returned", 400, e.code());
+      assertTrue(e.getMessage().contains("is not currently supported"));
+      assertTrue(e.getMessage().contains("text_general"));
+    }
+    
+
+  }
+
   public void testPivotFacetsMissing() throws Exception {
     doPivotFacetTest(true);
   }

Modified: lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java (original)
+++ lucene/dev/branches/lucene6005/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java Sat Nov  8 11:32:18 2014
@@ -180,7 +180,7 @@ public class TestJsonRecordReader  exten
     records = streamer.getAllRecords(new StringReader(json));
     assertEquals(2, records.size());
     for (Map<String, Object> record : records) {
-      assertEquals(6,record.size());
+      assertEquals(6, record.size());
       assertTrue(record.containsKey("subject"));
       assertTrue(record.containsKey("test"));
       assertTrue(record.containsKey("marks"));
@@ -203,4 +203,24 @@ public class TestJsonRecordReader  exten
 
   }
 
+  public void testNestedJsonWithFloats() throws Exception {
+
+    String json = "{\n" +
+        "        \"a_string\" : \"abc\",\n" +
+        "        \"a_num\" : 2.0,\n" +
+        "        \"a\" : {\n" +
+        "                        \"b\" : [\n" +
+        "                                {\"id\":\"1\", \"title\" : \"test1\"},\n" +
+        "                                {\"id\":\"2\", \"title\" : \"test2\"}\n" +
+        "                        ]\n" +
+        "                }\n" +
+        "}\n";
+
+    JsonRecordReader streamer;
+    List<Map<String, Object>> records;
+
+    streamer = JsonRecordReader.getInst("/a/b", Collections.singletonList("title_s:/a/b/title"));
+    records = streamer.getAllRecords(new StringReader(json));
+    assertEquals(2, records.size());
+  }
 }

Modified: lucene/dev/branches/lucene6005/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java?rev=1637544&r1=1637543&r2=1637544&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java (original)
+++ lucene/dev/branches/lucene6005/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java Sat Nov  8 11:32:18 2014
@@ -417,7 +417,9 @@ public class TestHarness extends BaseTes
       for (int i = 0; i < q.length; i += 2) {
         entries[i/2] = new NamedListEntry<>(q[i], q[i+1]);
       }
-      return new LocalSolrQueryRequest(TestHarness.this.getCore(), new NamedList(entries));
+      NamedList nl = new NamedList(entries);
+      if(nl.get("wt" ) == null) nl.add("wt","xml");
+      return new LocalSolrQueryRequest(TestHarness.this.getCore(), nl);
     }
   }