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 2015/10/15 12:25:42 UTC

svn commit: r1708778 [6/8] - in /lucene/dev/branches/lucene6825: ./ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/ l...

Modified: lucene/dev/branches/lucene6825/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java (original)
+++ lucene/dev/branches/lucene6825/solr/contrib/velocity/src/java/org/apache/solr/response/VelocityResponseWriter.java Thu Oct 15 10:25:39 2015
@@ -50,6 +50,7 @@ import org.apache.velocity.tools.generic
 import org.apache.velocity.tools.generic.DisplayTool;
 import org.apache.velocity.tools.generic.EscapeTool;
 import org.apache.velocity.tools.generic.ListTool;
+import org.apache.velocity.tools.generic.LocaleConfig;
 import org.apache.velocity.tools.generic.MathTool;
 import org.apache.velocity.tools.generic.NumberTool;
 import org.apache.velocity.tools.generic.ResourceTool;
@@ -194,17 +195,33 @@ public class VelocityResponseWriter impl
     VelocityContext context = new VelocityContext();
 
     // Register useful Velocity "tools"
+    String locale = request.getParams().get(LOCALE);
+    Map toolConfig = new HashMap();
+    toolConfig.put("locale", locale);
+
+
     context.put("log", log);   // TODO: add test; TODO: should this be overridable with a custom "log" named tool?
     context.put("esc", new EscapeTool());
     context.put("date", new ComparisonDateTool());
     context.put("list", new ListTool());
-    context.put("math", new MathTool());
-    context.put("number", new NumberTool());
     context.put("sort", new SortTool());
-    context.put("display", new DisplayTool());
-    context.put("resource", new SolrVelocityResourceTool(
-        request.getCore().getSolrConfig().getResourceLoader().getClassLoader(),
-        request.getParams().get(LOCALE)));
+
+    MathTool mathTool = new MathTool();
+    mathTool.configure(toolConfig);
+    context.put("math", mathTool);
+
+    NumberTool numberTool = new NumberTool();
+    numberTool.configure(toolConfig);
+    context.put("number", numberTool);
+
+
+    DisplayTool displayTool = new DisplayTool();
+    displayTool.configure(toolConfig);
+    context.put("display", displayTool);
+
+    ResourceTool resourceTool = new SolrVelocityResourceTool(request.getCore().getSolrConfig().getResourceLoader().getClassLoader());
+    resourceTool.configure(toolConfig);
+    context.put("resource", resourceTool);
 
 /*
     // Custom tools, specified in config as:
@@ -213,12 +230,14 @@ public class VelocityResponseWriter impl
             <str name="mytool">com.example.solr.velocity.MyTool</str>
           </lst>
         </queryResponseWriter>
-
-
 */
     // Custom tools can override any of the built-in tools provided above, by registering one with the same name
     for(String name : customTools.keySet()) {
-      context.put(name, SolrCore.createInstance(customTools.get(name), Object.class, "VrW custom tool", request.getCore(), request.getCore().getResourceLoader()));
+      Object customTool = SolrCore.createInstance(customTools.get(name), Object.class, "VrW custom tool: " + name, request.getCore(), request.getCore().getResourceLoader());
+      if (customTool instanceof LocaleConfig) {
+        ((LocaleConfig)customTool).configure(toolConfig);
+      }
+      context.put(name, customTool);
     }
 
     // custom tools _cannot_ override context objects added below, like $request and $response
@@ -359,10 +378,8 @@ public class VelocityResponseWriter impl
 
     private ClassLoader solrClassLoader;
 
-    public SolrVelocityResourceTool(ClassLoader cl, String localeString) {
+    public SolrVelocityResourceTool(ClassLoader cl) {
       this.solrClassLoader = cl;
-      Locale l = toLocale(localeString);
-      this.setLocale(l == null ? Locale.ROOT : l);
     }
 
     @Override

Modified: lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/MockTool.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/MockTool.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/MockTool.java (original)
+++ lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/MockTool.java Thu Oct 15 10:25:39 2015
@@ -18,8 +18,9 @@ package org.apache.solr.velocity;
  */
 
 import org.apache.solr.core.SolrCore;
+import org.apache.velocity.tools.generic.LocaleConfig;
 
-public class MockTool {
+public class MockTool extends LocaleConfig {
   private final SolrCore core;
 
   public MockTool(SolrCore core) {

Modified: lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java (original)
+++ lucene/dev/branches/lucene6825/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java Thu Oct 15 10:25:39 2015
@@ -121,7 +121,9 @@ public class VelocityResponseWriterTest
 
   @Test
   public void testCustomTools() throws Exception {
+    // custom_tool.vm responds with $!mytool.star("foo"), but $mytool is not defined (only in velocityWithCustomTools)
     assertEquals("", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"custom_tool")));
+
     assertEquals("** LATERALUS **", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
             SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t", "$mytool.star(\"LATERALUS\")")));
 
@@ -151,6 +153,16 @@ public class VelocityResponseWriterTest
 
     // Test that $resource.get(key,baseName,locale) works with specified locale
     assertEquals("Colour", h.query(req("q","*:*", "wt","velocity",VelocityResponseWriter.TEMPLATE,"resource_get")));
+
+    // Test that $number tool uses the specified locale
+    assertEquals("2,112", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
+        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t","$number.format(2112)", VelocityResponseWriter.LOCALE, "en_US")));
+    assertEquals("2.112", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
+        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t","$number.format(2112)", VelocityResponseWriter.LOCALE, "de_DE")));
+
+    // Test that custom tool extending LocaleConfig gets the right locale
+    assertEquals("de_DE", h.query(req("q","*:*", "wt","velocityWithCustomTools",VelocityResponseWriter.TEMPLATE,"t",
+        SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"t","$mytool.locale", VelocityResponseWriter.LOCALE, "de_DE")));
   }
 
   @Test

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java Thu Oct 15 10:25:39 2015
@@ -206,7 +206,7 @@ public class OverseerCollectionMessageHa
   @Override
   @SuppressWarnings("unchecked")
   public SolrResponse processMessage(ZkNodeProps message, String operation) {
-    log.warn("OverseerCollectionMessageHandler.processMessage : "+ operation + " , "+ message.toString());
+    log.info("OverseerCollectionMessageHandler.processMessage : "+ operation + " , "+ message.toString());
 
     NamedList results = new NamedList();
     try {

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerTaskQueue.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerTaskQueue.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerTaskQueue.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/cloud/OverseerTaskQueue.java Thu Oct 15 10:25:39 2015
@@ -29,6 +29,7 @@ import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,6 +92,9 @@ public class OverseerTaskQueue extends D
           + path.substring(path.lastIndexOf("-") + 1);
       if (zookeeper.exists(responsePath, true)) {
         zookeeper.setData(responsePath, event.getBytes(), true);
+      } else {
+        LOG.info("Response ZK path: " + responsePath + " doesn't exist."
+            + "  Requestor may have disconnected from ZooKeeper");
       }
       byte[] data = zookeeper.getData(path, null, null, true);
       zookeeper.delete(path, -1, true);
@@ -127,8 +131,8 @@ public class OverseerTaskQueue extends D
       Event.EventType eventType = event.getType();
       // None events are ignored
       // If latchEventType is not null, only fire if the type matches
+      LOG.info("{} fired on path {} state {} latchEventType {}", eventType, event.getPath(), event.getState(), latchEventType);
       if (eventType != Event.EventType.None && (latchEventType == null || eventType == latchEventType)) {
-        LOG.info("{} fired on path {} state {}", eventType, event.getPath(), event.getState());
         synchronized (lock) {
           this.event = event;
           lock.notifyAll();
@@ -176,22 +180,31 @@ public class OverseerTaskQueue extends D
       InterruptedException {
     TimerContext time = stats.time(dir + "_offer");
     try {
-      String path = createData(dir + "/" + PREFIX, data,
-          CreateMode.PERSISTENT_SEQUENTIAL);
+      // Create and watch the response node before creating the request node;
+      // otherwise we may miss the response.
       String watchID = createData(
-          dir + "/" + response_prefix + path.substring(path.lastIndexOf("-") + 1),
-          null, CreateMode.EPHEMERAL);
+          dir + "/" + response_prefix,
+          null, CreateMode.EPHEMERAL_SEQUENTIAL);
 
       Object lock = new Object();
       LatchWatcher watcher = new LatchWatcher(lock);
+      Stat stat = zookeeper.exists(watchID, watcher, true);
+
+      // create the request node
+      createData(dir + "/" + PREFIX + watchID.substring(watchID.lastIndexOf("-") + 1),
+          data, CreateMode.PERSISTENT);
+
       synchronized (lock) {
-        if (zookeeper.exists(watchID, watcher, true) != null) {
+        if (stat != null && watcher.getWatchedEvent() == null) {
           watcher.await(timeout);
         }
       }
       byte[] bytes = zookeeper.getData(watchID, null, null, true);
+      // create the event before deleting the node, otherwise we can get the deleted
+      // event from the watcher.
+      QueueEvent event =  new QueueEvent(watchID, bytes, watcher.getWatchedEvent());
       zookeeper.delete(watchID, -1, true);
-      return new QueueEvent(watchID, bytes, watcher.getWatchedEvent());
+      return event;
     } finally {
       time.stop();
     }

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java Thu Oct 15 10:25:39 2015
@@ -99,6 +99,7 @@ public class ImplicitPlugins {
   public static PluginInfo getReqHandlerInfo(String name, Class clz, Map defaults){
     if(defaults == null) defaults= Collections.emptyMap();
     Map m = makeMap(NAME, name, "class", clz.getName());
-    return new PluginInfo(SolrRequestHandler.TYPE, m, new NamedList<>(singletonMap(DEFAULTS, new NamedList(defaults))),null);
+    // be explicit with generics, because Java 9 fails to compile otherwise (type inference: Map.Entry[] vs. singletonMap):
+    return new PluginInfo(SolrRequestHandler.TYPE, m, new NamedList<>(Collections.<String,Object>singletonMap(DEFAULTS, new NamedList<>(defaults))),null);
   }
 }

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java Thu Oct 15 10:25:39 2015
@@ -140,8 +140,16 @@ public class SolrResourceLoader implemen
     }
     
     this.classLoader = createClassLoader(null, parent);
-    addToClassLoader("./lib/", null, true);
-    reloadLuceneSPI();
+    /* 
+     * Skip the lib subdirectory when we are loading from the solr home.
+     * Otherwise load it, so core lib directories still get loaded.
+     * The default sharedLib will pick this up later, and if the user has
+     * changed sharedLib, then we don't want to load that location anyway.
+     */
+    if (! this.instanceDir.equals(SolrResourceLoader.locateSolrHome())) {
+      addToClassLoader("./lib/", null, true);
+      reloadLuceneSPI();
+    }
     this.coreProperties = coreProperties;
   }
 

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/SQLHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/SQLHandler.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/SQLHandler.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/SQLHandler.java Thu Oct 15 10:25:39 2015
@@ -33,15 +33,20 @@ import org.apache.solr.client.solrj.io.c
 import org.apache.solr.client.solrj.io.comp.FieldComparator;
 import org.apache.solr.client.solrj.io.comp.MultipleFieldComparator;
 import org.apache.solr.client.solrj.io.comp.StreamComparator;
+import org.apache.solr.client.solrj.io.eq.FieldEqualitor;
+import org.apache.solr.client.solrj.io.eq.MultipleFieldEqualitor;
+import org.apache.solr.client.solrj.io.eq.StreamEqualitor;
 import org.apache.solr.client.solrj.io.stream.CloudSolrStream;
 import org.apache.solr.client.solrj.io.stream.FacetStream;
 import org.apache.solr.client.solrj.io.stream.ParallelStream;
 import org.apache.solr.client.solrj.io.stream.RankStream;
+import org.apache.solr.client.solrj.io.stream.EditStream;
 import org.apache.solr.client.solrj.io.stream.RollupStream;
 import org.apache.solr.client.solrj.io.stream.StatsStream;
 import org.apache.solr.client.solrj.io.stream.StreamContext;
 import org.apache.solr.client.solrj.io.stream.TupleStream;
 import org.apache.solr.client.solrj.io.stream.ExceptionStream;
+import org.apache.solr.client.solrj.io.stream.UniqueStream;
 import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
 import org.apache.solr.client.solrj.io.stream.metrics.*;
 import org.apache.solr.common.SolrException;
@@ -66,6 +71,12 @@ public class SQLHandler extends RequestH
 
   private static String defaultZkhost = null;
   private static String defaultWorkerCollection = null;
+  private static List<String> remove;
+
+  static {
+    remove = new ArrayList();
+    remove.add("count(*)");
+  }
 
   private Logger logger = LoggerFactory.getLogger(SQLHandler.class);
 
@@ -83,7 +94,7 @@ public class SQLHandler extends RequestH
     SolrParams params = req.getParams();
     params = adjustParams(params);
     req.setParams(params);
-    String sql = params.get("sql");
+    String sql = params.get("stmt");
     int numWorkers = params.getInt("numWorkers", 1);
     String workerCollection = params.get("workerCollection", defaultWorkerCollection);
     String workerZkhost = params.get("workerZkhost",defaultZkhost);
@@ -144,6 +155,12 @@ public class SQLHandler extends RequestH
         } else {
           sqlStream = doGroupByWithAggregates(sqlVistor, numWorkers, workerCollection, workerZkhost);
         }
+      } else if(sqlVistor.isDistinct) {
+        if(aggregationMode == AggregationMode.FACET) {
+          sqlStream = doSelectDistinctFacets(sqlVistor);
+        } else {
+          sqlStream = doSelectDistinct(sqlVistor, numWorkers, workerCollection, workerZkhost);
+        }
       } else {
         sqlStream = doSelect(sqlVistor);
       }
@@ -238,6 +255,201 @@ public class SQLHandler extends RequestH
     return tupleStream;
   }
 
+  private static TupleStream doSelectDistinct(SQLVisitor sqlVisitor,
+                                              int numWorkers,
+                                              String workerCollection,
+                                              String workerZkHost) throws IOException {
+
+    Set<String> fieldSet = new HashSet();
+    Bucket[] buckets = getBuckets(sqlVisitor.fields, fieldSet);
+    Metric[] metrics = getMetrics(sqlVisitor.fields, fieldSet);
+
+    if(metrics.length > 0) {
+      throw new IOException("Select Distinct queries cannot include aggregate functions.");
+    }
+
+    String fl = fields(fieldSet);
+
+    String sort = null;
+    StreamEqualitor ecomp = null;
+    StreamComparator comp = null;
+
+    if(sqlVisitor.sorts != null && sqlVisitor.sorts.size() > 0) {
+      StreamComparator[] adjustedSorts = adjustSorts(sqlVisitor.sorts, buckets);
+      FieldEqualitor[] fieldEqualitors = new FieldEqualitor[adjustedSorts.length];
+      StringBuilder buf = new StringBuilder();
+      for(int i=0; i<adjustedSorts.length; i++) {
+        FieldComparator fieldComparator = (FieldComparator)adjustedSorts[i];
+        fieldEqualitors[i] = new FieldEqualitor(fieldComparator.getFieldName());
+        if(i>0) {
+          buf.append(",");
+        }
+        buf.append(fieldComparator.getFieldName()).append(" ").append(fieldComparator.getOrder().toString());
+      }
+
+      sort = buf.toString();
+
+      if(adjustedSorts.length == 1) {
+        ecomp = fieldEqualitors[0];
+        comp = adjustedSorts[0];
+      } else {
+        ecomp = new MultipleFieldEqualitor(fieldEqualitors);
+        comp = new MultipleFieldComparator(adjustedSorts);
+      }
+    } else {
+      StringBuilder sortBuf = new StringBuilder();
+      FieldEqualitor[] equalitors = new FieldEqualitor[buckets.length];
+      StreamComparator[] streamComparators = new StreamComparator[buckets.length];
+      for(int i=0; i<buckets.length; i++) {
+        equalitors[i] = new FieldEqualitor(buckets[i].toString());
+        streamComparators[i] = new FieldComparator(buckets[i].toString(), ComparatorOrder.ASCENDING);
+        if(i>0) {
+          sortBuf.append(',');
+        }
+        sortBuf.append(buckets[i].toString()).append(" asc");
+      }
+
+      sort = sortBuf.toString();
+
+      if(equalitors.length == 1) {
+        ecomp = equalitors[0];
+        comp = streamComparators[0];
+      } else {
+        ecomp = new MultipleFieldEqualitor(equalitors);
+        comp = new MultipleFieldComparator(streamComparators);
+      }
+    }
+
+    TableSpec tableSpec = new TableSpec(sqlVisitor.table, defaultZkhost);
+
+    String zkHost = tableSpec.zkHost;
+    String collection = tableSpec.collection;
+    Map<String, String> params = new HashMap();
+
+    params.put(CommonParams.FL, fl);
+    params.put(CommonParams.Q, sqlVisitor.query);
+    //Always use the /export handler for Distinct Queries because it requires exporting full result sets.
+    params.put(CommonParams.QT, "/export");
+
+    if(numWorkers > 1) {
+      params.put("partitionKeys", getPartitionKeys(buckets));
+    }
+
+    params.put("sort", sort);
+
+    TupleStream tupleStream = null;
+
+    CloudSolrStream cstream = new CloudSolrStream(zkHost, collection, params);
+    tupleStream = new UniqueStream(cstream, ecomp);
+
+    if(numWorkers > 1) {
+      // Do the unique in parallel
+      // Maintain the sort of the Tuples coming from the workers.
+      ParallelStream parallelStream = new ParallelStream(workerZkHost, workerCollection, tupleStream, numWorkers, comp);
+
+      StreamFactory factory = new StreamFactory()
+          .withFunctionName("search", CloudSolrStream.class)
+          .withFunctionName("parallel", ParallelStream.class)
+          .withFunctionName("unique", UniqueStream.class);
+
+      parallelStream.setStreamFactory(factory);
+      parallelStream.setObjectSerialize(false);
+      tupleStream = parallelStream;
+    }
+
+    if(sqlVisitor.limit > 0) {
+      tupleStream = new LimitStream(tupleStream, sqlVisitor.limit);
+    }
+
+    return tupleStream;
+  }
+
+  private static StreamComparator[] adjustSorts(List<SortItem> sorts, Bucket[] buckets) throws IOException {
+    List<FieldComparator> adjustedSorts = new ArrayList();
+    Set<String> bucketFields = new HashSet();
+    Set<String> sortFields = new HashSet();
+
+    for(SortItem sortItem : sorts) {
+
+      sortFields.add(getSortField(sortItem));
+      adjustedSorts.add(new FieldComparator(getSortField(sortItem),
+                                            ascDescComp(sortItem.getOrdering().toString())));
+    }
+
+    for(Bucket bucket : buckets) {
+      bucketFields.add(bucket.toString());
+    }
+
+    for(SortItem sortItem : sorts) {
+      String sortField = getSortField(sortItem);
+      if(!bucketFields.contains(sortField)) {
+        throw new IOException("All sort fields must be in the field list.");
+      }
+    }
+
+    //Add sort fields if needed
+    if(sorts.size() < buckets.length) {
+      for(Bucket bucket : buckets) {
+        String b = bucket.toString();
+        if(!sortFields.contains(b)) {
+          adjustedSorts.add(new FieldComparator(bucket.toString(), ComparatorOrder.ASCENDING));
+        }
+      }
+    }
+
+    return adjustedSorts.toArray(new FieldComparator[adjustedSorts.size()]);
+  }
+
+  private static TupleStream doSelectDistinctFacets(SQLVisitor sqlVisitor) throws IOException {
+
+    Set<String> fieldSet = new HashSet();
+    Bucket[] buckets = getBuckets(sqlVisitor.fields, fieldSet);
+    Metric[] metrics = getMetrics(sqlVisitor.fields, fieldSet);
+
+    if(metrics.length > 0) {
+      throw new IOException("Select Distinct queries cannot include aggregate functions.");
+    }
+
+    TableSpec tableSpec = new TableSpec(sqlVisitor.table, defaultZkhost);
+
+    String zkHost = tableSpec.zkHost;
+    String collection = tableSpec.collection;
+    Map<String, String> params = new HashMap();
+
+    params.put(CommonParams.Q, sqlVisitor.query);
+
+    int limit = sqlVisitor.limit > 0 ? sqlVisitor.limit : 100;
+
+    FieldComparator[] sorts = null;
+
+    if(sqlVisitor.sorts == null) {
+      sorts = new FieldComparator[buckets.length];
+      for(int i=0; i<sorts.length; i++) {
+        sorts[i] = new FieldComparator("index", ComparatorOrder.ASCENDING);
+      }
+    } else {
+      StreamComparator[] comps = adjustSorts(sqlVisitor.sorts, buckets);
+      sorts = new FieldComparator[comps.length];
+      for(int i=0; i<comps.length; i++) {
+        sorts[i] = (FieldComparator)comps[i];
+      }
+    }
+
+    TupleStream tupleStream = new FacetStream(zkHost,
+                                              collection,
+                                              params,
+                                              buckets,
+                                              metrics,
+                                              sorts,
+                                              limit);
+
+    if(sqlVisitor.limit > 0) {
+      tupleStream = new LimitStream(tupleStream, sqlVisitor.limit);
+    }
+
+    return new EditStream(tupleStream, remove);
+  }
+
   private static TupleStream doGroupByWithAggregatesFacets(SQLVisitor sqlVisitor) throws IOException {
 
     Set<String> fieldSet = new HashSet();
@@ -344,7 +556,7 @@ public class SQLHandler extends RequestH
         if (comma) {
           siBuf.append(",");
         }
-        siBuf.append(stripQuotes(sortItem.getSortKey().toString()) + " " + ascDesc(sortItem.getOrdering().toString()));
+        siBuf.append(getSortField(sortItem) + " " + ascDesc(sortItem.getOrdering().toString()));
       }
     } else {
       if(sqlVisitor.limit < 0) {
@@ -388,7 +600,7 @@ public class SQLHandler extends RequestH
     for(int i=0; i< buckets.length; i++) {
       Bucket bucket = buckets[i];
       SortItem sortItem = sortItems.get(i);
-      if(!bucket.toString().equals(stripQuotes(sortItem.getSortKey().toString()))) {
+      if(!bucket.toString().equals(getSortField(sortItem))) {
         return false;
       }
 
@@ -450,10 +662,10 @@ public class SQLHandler extends RequestH
     return buf.toString();
   }
 
-  public static String getSortDirection(List<SortItem> sorts) {
+  private static String getSortDirection(List<SortItem> sorts) {
     if(sorts != null && sorts.size() > 0) {
       for(SortItem item : sorts) {
-        return ascDesc(stripQuotes(item.getOrdering().toString()));
+        return ascDesc(stripSingleQuotes(stripQuotes(item.getOrdering().toString())));
       }
     }
 
@@ -481,8 +693,8 @@ public class SQLHandler extends RequestH
       SortItem sortItem = sortItems.get(i);
       String ordering = sortItem.getOrdering().toString();
       ComparatorOrder comparatorOrder = ascDescComp(ordering);
-      String sortKey = sortItem.getSortKey().toString();
-      comps[i] = new FieldComparator(stripQuotes(sortKey), comparatorOrder);
+      String sortKey = getSortField(sortItem);
+      comps[i] = new FieldComparator(sortKey, comparatorOrder);
     }
 
     if(comps.length == 1) {
@@ -498,8 +710,8 @@ public class SQLHandler extends RequestH
       SortItem sortItem = sortItems.get(i);
       String ordering = sortItem.getOrdering().toString();
       ComparatorOrder comparatorOrder = ascDescComp(ordering);
-      String sortKey = sortItem.getSortKey().toString();
-      comps[i] = new FieldComparator(stripQuotes(sortKey), comparatorOrder);
+      String sortKey = getSortField(sortItem);
+      comps[i] = new FieldComparator(sortKey, comparatorOrder);
     }
 
     return comps;
@@ -644,7 +856,7 @@ public class SQLHandler extends RequestH
     }
 
     protected Void visitComparisonExpression(ComparisonExpression node, StringBuilder buf) {
-      String field = node.getLeft().toString();
+      String field = getPredicateField(node.getLeft());
       String value = node.getRight().toString();
       value = stripSingleQuotes(value);
 
@@ -653,7 +865,7 @@ public class SQLHandler extends RequestH
         value = '"'+value+'"';
       }
 
-      buf.append('(').append(stripQuotes(field) + ":" + value).append(')');
+      buf.append('(').append(field + ":" + value).append(')');
       return null;
     }
   }
@@ -668,6 +880,7 @@ public class SQLHandler extends RequestH
     public int limit = -1;
     public boolean groupByQuery;
     public Expression havingExpression;
+    public boolean isDistinct;
 
     public SQLVisitor(StringBuilder builder) {
       this.builder = builder;
@@ -731,8 +944,7 @@ public class SQLHandler extends RequestH
         this.groupByQuery = true;
         List<Expression> groups = node.getGroupBy();
         for(Expression group : groups) {
-          groupBy.add(stripQuotes(group.toString()));
-
+          groupBy.add(getGroupField(group));
         }
       }
 
@@ -756,14 +968,14 @@ public class SQLHandler extends RequestH
     protected Void visitComparisonExpression(ComparisonExpression node, Integer index) {
       String field = node.getLeft().toString();
       String value = node.getRight().toString();
-      query = stripQuotes(field)+":"+stripQuotes(value);
+      query = stripSingleQuotes(stripQuotes(field))+":"+stripQuotes(value);
       return null;
     }
 
     protected Void visitSelect(Select node, Integer indent) {
       this.append(indent.intValue(), "SELECT");
       if(node.isDistinct()) {
-
+        this.isDistinct = true;
       }
 
       if(node.getSelectItems().size() > 1) {
@@ -781,7 +993,37 @@ public class SQLHandler extends RequestH
     }
 
     protected Void visitSingleColumn(SingleColumn node, Integer indent) {
-      fields.add(stripQuotes(ExpressionFormatter.formatExpression(node.getExpression())));
+
+      Expression ex = node.getExpression();
+      String field = null;
+
+      if(ex instanceof QualifiedNameReference) {
+
+        QualifiedNameReference ref = (QualifiedNameReference)ex;
+        List<String> parts = ref.getName().getOriginalParts();
+        field = parts.get(0);
+
+      } else if(ex instanceof  FunctionCall) {
+
+        FunctionCall functionCall = (FunctionCall)ex;
+        List<String> parts = functionCall.getName().getOriginalParts();
+        List<Expression> args = functionCall.getArguments();
+        String col = null;
+
+        if(args.size() > 0 && args.get(0) instanceof QualifiedNameReference) {
+          QualifiedNameReference ref = (QualifiedNameReference) args.get(0);
+          col = ref.getName().getOriginalParts().get(0);
+          field = parts.get(0)+"("+stripSingleQuotes(col)+")";
+        } else {
+          field = stripSingleQuotes(stripQuotes(functionCall.toString()));
+        }
+
+      } else if(ex instanceof StringLiteral) {
+        StringLiteral stringLiteral = (StringLiteral)ex;
+        field = stripSingleQuotes(stringLiteral.toString());
+      }
+
+      fields.add(field);
 
       if(node.getAlias().isPresent()) {
       }
@@ -789,12 +1031,15 @@ public class SQLHandler extends RequestH
       return null;
     }
 
+
+
+
     protected Void visitAllColumns(AllColumns node, Integer context) {
       return null;
     }
 
     protected Void visitTable(Table node, Integer indent) {
-      this.table = node.getName().toString();
+      this.table = stripSingleQuotes(node.getName().toString());
       return null;
     }
 
@@ -830,6 +1075,98 @@ public class SQLHandler extends RequestH
     }
   }
 
+  private static String getSortField(SortItem sortItem)
+  {
+    String field;
+    Expression ex = sortItem.getSortKey();
+    if(ex instanceof QualifiedNameReference) {
+      QualifiedNameReference ref = (QualifiedNameReference)ex;
+      List<String> parts = ref.getName().getOriginalParts();
+      field = parts.get(0);
+    } else if(ex instanceof  FunctionCall) {
+      FunctionCall functionCall = (FunctionCall)ex;
+      List<String> parts = functionCall.getName().getOriginalParts();
+      List<Expression> args = functionCall.getArguments();
+      String col = null;
+
+      if(args.size() > 0 && args.get(0) instanceof QualifiedNameReference) {
+        QualifiedNameReference ref = (QualifiedNameReference) args.get(0);
+        col = ref.getName().getOriginalParts().get(0);
+        field = parts.get(0)+"("+stripSingleQuotes(col)+")";
+      } else {
+        field = stripSingleQuotes(stripQuotes(functionCall.toString()));
+      }
+
+    } else {
+      StringLiteral stringLiteral = (StringLiteral)ex;
+      field = stripSingleQuotes(stringLiteral.toString());
+    }
+
+    return field;
+  }
+
+
+  private static String getHavingField(Expression ex)
+  {
+    String field;
+    if(ex instanceof QualifiedNameReference) {
+      QualifiedNameReference ref = (QualifiedNameReference)ex;
+      List<String> parts = ref.getName().getOriginalParts();
+      field = parts.get(0);
+    } else if(ex instanceof  FunctionCall) {
+      FunctionCall functionCall = (FunctionCall)ex;
+      List<String> parts = functionCall.getName().getOriginalParts();
+      List<Expression> args = functionCall.getArguments();
+      String col = null;
+
+      if(args.size() > 0 && args.get(0) instanceof QualifiedNameReference) {
+        QualifiedNameReference ref = (QualifiedNameReference) args.get(0);
+        col = ref.getName().getOriginalParts().get(0);
+        field = parts.get(0)+"("+stripSingleQuotes(col)+")";
+      } else {
+        field = stripSingleQuotes(stripQuotes(functionCall.toString()));
+      }
+
+    } else {
+      StringLiteral stringLiteral = (StringLiteral)ex;
+      field = stripSingleQuotes(stringLiteral.toString());
+    }
+
+    return field;
+  }
+
+
+  private static String getPredicateField(Expression ex)
+  {
+    String field;
+    if(ex instanceof QualifiedNameReference) {
+      QualifiedNameReference ref = (QualifiedNameReference)ex;
+      List<String> parts = ref.getName().getOriginalParts();
+      field = parts.get(0);
+    } else {
+      StringLiteral stringLiteral = (StringLiteral)ex;
+      field = stripSingleQuotes(stringLiteral.toString());
+    }
+
+    return field;
+  }
+
+  private static String getGroupField(Expression ex)
+  {
+    String field;
+    if(ex instanceof QualifiedNameReference) {
+      QualifiedNameReference ref = (QualifiedNameReference)ex;
+      List<String> parts = ref.getName().getOriginalParts();
+      field = parts.get(0);
+    } else {
+      StringLiteral stringLiteral = (StringLiteral)ex;
+      field = stripSingleQuotes(stringLiteral.toString());
+    }
+
+    return field;
+  }
+
+
   private static class LimitStream extends TupleStream {
 
     private TupleStream stream;
@@ -892,7 +1229,7 @@ public class SQLHandler extends RequestH
     }
   }
 
-  public static class HavingStream extends TupleStream {
+  private static class HavingStream extends TupleStream {
 
     private TupleStream stream;
     private HavingVisitor havingVisitor;
@@ -963,7 +1300,7 @@ public class SQLHandler extends RequestH
     }
 
     protected Boolean visitComparisonExpression(ComparisonExpression node, Tuple tuple) {
-      String field = stripQuotes(node.getLeft().toString());
+      String field = getHavingField(node.getLeft());
       double d = Double.parseDouble(node.getRight().toString());
       double td = tuple.getDouble(field);
       ComparisonExpression.Type t = node.getType();

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java Thu Oct 15 10:25:39 2015
@@ -54,7 +54,7 @@ import org.apache.lucene.search.Collecto
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.LeafCollector;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryWrapperFilter;
+import org.apache.solr.search.QueryWrapperFilter;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Sort;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java Thu Oct 15 10:25:39 2015
@@ -186,7 +186,7 @@ public class SuggestComponent extends Se
       rb.rsp.add("command", (!reloadAll) ? "reload" : "reloadAll");
     }
   }
-  
+
   /** Dispatch shard request in <code>STAGE_EXECUTE_QUERY</code> stage */
   @Override
   public int distributedProcess(ResponseBuilder rb) {
@@ -238,11 +238,21 @@ public class SuggestComponent extends Se
         query = params.get(CommonParams.Q);
       }
     }
-    
+
     if (query != null) {
       int count = params.getInt(SUGGEST_COUNT, 1);
-      SuggesterOptions options = new SuggesterOptions(new CharsRef(query), count);
-      Map<String, SimpleOrderedMap<NamedList<Object>>> namedListResults = 
+      boolean highlight = params.getBool(SUGGEST_HIGHLIGHT, false);
+      boolean allTermsRequired = params.getBool(SUGGEST_ALL_TERMS_REQUIRED, true);
+      String contextFilter = params.get(SUGGEST_CONTEXT_FILTER_QUERY);
+      if (contextFilter != null) {
+        contextFilter = contextFilter.trim();
+        if (contextFilter.length() == 0) {
+          contextFilter = null;
+        }
+      }
+
+      SuggesterOptions options = new SuggesterOptions(new CharsRef(query), count, contextFilter, allTermsRequired, highlight);
+      Map<String, SimpleOrderedMap<NamedList<Object>>> namedListResults =
           new HashMap<>();
       for (SolrSuggester suggester : querySuggesters) {
         SuggesterResult suggesterResult = suggester.getSuggestions(options);
@@ -251,7 +261,7 @@ public class SuggestComponent extends Se
       rb.rsp.add(SuggesterResultLabels.SUGGEST, namedListResults);
     }
   }
-  
+
   /** 
    * Used in Distributed Search, merges the suggestion results from every shard
    * */

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java Thu Oct 15 10:25:39 2015
@@ -37,14 +37,12 @@ import org.apache.lucene.search.Constant
 import org.apache.lucene.search.ConstantScoreWeight;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.AttributeSource;
-import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.DocIdSetBuilder;
 import org.apache.lucene.util.FixedBitSet;
@@ -53,7 +51,7 @@ import org.apache.solr.search.DocSet;
 import org.apache.solr.search.DocSetBuilder;
 import org.apache.solr.search.DocSetProducer;
 import org.apache.solr.search.ExtendedQueryBase;
-import org.apache.solr.search.SolrConstantScoreQuery;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.SolrIndexSearcher;
 
 /** @lucene.experimental */

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java Thu Oct 15 10:25:39 2015
@@ -26,7 +26,6 @@ import org.apache.lucene.index.SortedDoc
 import org.apache.lucene.index.SortedSetDocValues;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.CharsRefBuilder;
@@ -37,6 +36,7 @@ import org.apache.solr.common.util.Named
 import org.apache.solr.schema.FieldType;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.search.DocSet;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.util.LongPriorityQueue;
 

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesStats.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesStats.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesStats.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/DocValuesStats.java Thu Oct 15 10:25:39 2015
@@ -30,7 +30,6 @@ import org.apache.lucene.index.SortedDoc
 import org.apache.lucene.index.SortedSetDocValues;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.LongValues;
 import org.apache.solr.common.SolrException;
@@ -41,6 +40,7 @@ import org.apache.solr.handler.component
 import org.apache.solr.schema.FieldType;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.search.DocSet;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.SolrIndexSearcher;
 
 /**

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/IntervalFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/IntervalFacets.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/IntervalFacets.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/IntervalFacets.java Thu Oct 15 10:25:39 2015
@@ -17,7 +17,6 @@ import org.apache.lucene.index.SortedDoc
 import org.apache.lucene.index.SortedSetDocValues;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.NumericUtils;
@@ -30,6 +29,7 @@ import org.apache.solr.schema.SchemaFiel
 import org.apache.solr.schema.TrieDateField;
 import org.apache.solr.search.DocIterator;
 import org.apache.solr.search.DocSet;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.QueryParsing;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.search.SyntaxError;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java Thu Oct 15 10:25:39 2015
@@ -23,7 +23,6 @@ import org.apache.lucene.index.SortedDoc
 import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.CharsRefBuilder;
@@ -34,6 +33,7 @@ import org.apache.solr.common.params.Fac
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.schema.FieldType;
 import org.apache.solr.search.DocSet;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.util.BoundedTreeSet;
 

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/SimpleFacets.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/SimpleFacets.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/request/SimpleFacets.java Thu Oct 15 10:25:39 2015
@@ -29,7 +29,6 @@ import org.apache.lucene.index.TermsEnum
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.FilterCollector;
 import org.apache.lucene.search.LeafCollector;
 import org.apache.lucene.search.Query;
@@ -62,6 +61,7 @@ import org.apache.solr.schema.SchemaFiel
 import org.apache.solr.schema.TrieField;
 import org.apache.solr.search.BitDocSet;
 import org.apache.solr.search.DocSet;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.Grouping;
 import org.apache.solr.search.HashDocSet;
 import org.apache.solr.search.Insanity;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java Thu Oct 15 10:25:39 2015
@@ -21,7 +21,6 @@ import java.io.IOException;
 import org.apache.lucene.index.StorableField;
 import org.apache.lucene.index.StoredDocument;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryWrapperFilter;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.join.QueryBitSetProducer;
 import org.apache.lucene.search.join.BitSetProducer;
@@ -38,6 +37,7 @@ import org.apache.solr.schema.SchemaFiel
 import org.apache.solr.search.DocIterator;
 import org.apache.solr.search.DocList;
 import org.apache.solr.search.QParser;
+import org.apache.solr.search.QueryWrapperFilter;
 import org.apache.solr.search.SyntaxError;
 
 /**

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/schema/CurrencyField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/schema/CurrencyField.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/schema/CurrencyField.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/schema/CurrencyField.java Thu Oct 15 10:25:39 2015
@@ -42,15 +42,15 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.FieldValueQuery;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryWrapperFilter;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.uninverting.UninvertingReader.Type;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.response.TextResponseWriter;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.QParser;
+import org.apache.solr.search.QueryWrapperFilter;
 import org.apache.solr.search.SolrConstantScoreQuery;
 import org.apache.solr.search.function.ValueSourceRangeFilter;
 import org.slf4j.Logger;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/BitDocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/BitDocSet.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/BitDocSet.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/BitDocSet.java Thu Oct 15 10:25:39 2015
@@ -22,10 +22,8 @@ import java.util.Collections;
 
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.BitsFilteredDocIdSet;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.BitDocIdSet;
 import org.apache.lucene.util.BitSetIterator;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSet.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSet.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSet.java Thu Oct 15 10:25:39 2015
@@ -19,7 +19,6 @@ package org.apache.solr.search;
 
 import java.io.Closeable;
 
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.Accountable;
 import org.apache.solr.common.SolrException;
 

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetBase.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetBase.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetBase.java Thu Oct 15 10:25:39 2015
@@ -21,10 +21,8 @@ import java.io.IOException;
 
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.BitsFilteredDocIdSet;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BitDocIdSet;
 import org.apache.lucene.util.FixedBitSet;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetUtil.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetUtil.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/DocSetUtil.java Thu Oct 15 10:25:39 2015
@@ -20,10 +20,8 @@ package org.apache.solr.search;
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.ExitableDirectoryReader;
 import org.apache.lucene.index.Fields;
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
@@ -31,12 +29,9 @@ import org.apache.lucene.index.PostingsE
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.util.Bits;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/Grouping.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/Grouping.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/Grouping.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/Grouping.java Thu Oct 15 10:25:39 2015
@@ -36,7 +36,6 @@ import org.apache.lucene.search.BooleanC
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.CachingCollector;
 import org.apache.lucene.search.Collector;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.MultiCollector;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java Thu Oct 15 10:25:39 2015
@@ -18,49 +18,34 @@
 package org.apache.solr.search;
 
 import java.io.IOException;
-import java.io.Serializable;
 import java.util.List;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.Future;
-import com.google.common.primitives.Longs;
 
+import org.apache.lucene.index.IndexReaderContext;
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.SortedDocValues;
+import org.apache.lucene.search.ConstantScoreQuery;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.LeafCollector;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.BitDocIdSet;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.CharsRef;
 import org.apache.lucene.util.CharsRefBuilder;
 import org.apache.lucene.util.FixedBitSet;
-
-import org.apache.lucene.util.Bits;
-import org.apache.lucene.search.BitsFilteredDocIdSet;
 import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.common.util.SolrjNamedThreadFactory;
-import org.apache.solr.core.CloseHook;
+import org.apache.solr.common.util.NamedList;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.StrField;
-import org.apache.solr.schema.TrieField;
-import org.apache.solr.core.SolrCore;
 
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ConstantScoreQuery;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Weight;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.index.SortedDocValues;
-import org.apache.lucene.index.NumericDocValues;
-import org.apache.lucene.util.BytesRef;
-
-import org.apache.solr.common.util.NamedList;
+import com.google.common.primitives.Longs;
 
 /**
 * syntax fq={!hash workers=11 worker=4 keys=field1,field2}

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java Thu Oct 15 10:25:39 2015
@@ -33,7 +33,6 @@ import org.apache.lucene.search.Constant
 import org.apache.lucene.search.ConstantScoreWeight;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/QParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/QParserPlugin.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/QParserPlugin.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/QParserPlugin.java Thu Oct 15 10:25:39 2015
@@ -22,6 +22,7 @@ import org.apache.solr.core.SolrInfoMBea
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.search.join.BlockJoinChildQParserPlugin;
 import org.apache.solr.search.join.BlockJoinParentQParserPlugin;
+import org.apache.solr.search.join.GraphQParserPlugin;
 import org.apache.solr.search.mlt.MLTQParserPlugin;
 import org.apache.solr.util.plugin.NamedListInitializedPlugin;
 
@@ -73,6 +74,7 @@ public abstract class QParserPlugin impl
     map.put(ExportQParserPlugin.NAME, ExportQParserPlugin.class);
     map.put(MLTQParserPlugin.NAME, MLTQParserPlugin.class);
     map.put(HashQParserPlugin.NAME, HashQParserPlugin.class);
+    map.put(GraphQParserPlugin.NAME, GraphQParserPlugin.class);
     standardPlugins = Collections.unmodifiableMap(map);
   }
 

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java Thu Oct 15 10:25:39 2015
@@ -3,14 +3,12 @@ package org.apache.solr.search;
 import java.io.IOException;
 import java.util.Map;
 
-import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.search.ConstantScoreScorer;
 import org.apache.lucene.search.ConstantScoreWeight;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrFilter.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrFilter.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SolrFilter.java Thu Oct 15 10:25:39 2015
@@ -18,7 +18,6 @@
 package org.apache.solr.search;
 
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.util.Bits;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java Thu Oct 15 10:25:39 2015
@@ -22,10 +22,8 @@ import java.util.Collections;
 
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.BitsFilteredDocIdSet;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.FixedBitSet;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/TermsQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/TermsQParserPlugin.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/TermsQParserPlugin.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/TermsQParserPlugin.java Thu Oct 15 10:25:39 2015
@@ -26,10 +26,8 @@ import org.apache.lucene.search.Automato
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.DocValuesTermsQuery;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryWrapperFilter;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/facet/FacetField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/facet/FacetField.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/facet/FacetField.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/facet/FacetField.java Thu Oct 15 10:25:39 2015
@@ -39,7 +39,6 @@ import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.util.BytesRef;
@@ -54,6 +53,7 @@ import org.apache.solr.schema.FieldType;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.schema.TrieField;
 import org.apache.solr.search.DocSet;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.HashDocSet;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.search.SortedIntDocSet;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java Thu Oct 15 10:25:39 2015
@@ -22,8 +22,8 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.BitsFilteredDocIdSet;
 import org.apache.lucene.util.Bits;
+import org.apache.solr.search.BitsFilteredDocIdSet;
 import org.apache.solr.search.SolrFilter;
 
 import java.io.IOException;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java Thu Oct 15 10:25:39 2015
@@ -27,14 +27,12 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.Collector;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.MultiCollector;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TimeLimitingCollector;
 import org.apache.lucene.search.TotalHitCountCollector;
 import org.apache.lucene.search.grouping.AbstractAllGroupHeadsCollector;
 import org.apache.lucene.search.grouping.function.FunctionAllGroupHeadsCollector;
-import org.apache.lucene.search.grouping.function.FunctionAllGroupsCollector;
 import org.apache.lucene.search.grouping.term.TermAllGroupHeadsCollector;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.schema.FieldType;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/SearchGroupsResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/SearchGroupsResultTransformer.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/SearchGroupsResultTransformer.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/SearchGroupsResultTransformer.java Thu Oct 15 10:25:39 2015
@@ -38,6 +38,9 @@ import java.util.*;
  */
 public class SearchGroupsResultTransformer implements ShardResultTransformer<List<Command>, Map<String, SearchGroupsFieldCommandResult>> {
 
+  private static final String TOP_GROUPS = "topGroups";
+  private static final String GROUP_COUNT = "groupCount";
+
   private final SolrIndexSearcher searcher;
 
   public SearchGroupsResultTransformer(SolrIndexSearcher searcher) {
@@ -49,19 +52,19 @@ public class SearchGroupsResultTransform
    */
   @Override
   public NamedList transform(List<Command> data) throws IOException {
-    NamedList<NamedList> result = new NamedList<>();
+    final NamedList<NamedList> result = new NamedList<>(data.size());
     for (Command command : data) {
-      final NamedList<Object> commandResult = new NamedList<>();
+      final NamedList<Object> commandResult = new NamedList<>(2);
       if (SearchGroupsFieldCommand.class.isInstance(command)) {
         SearchGroupsFieldCommand fieldCommand = (SearchGroupsFieldCommand) command;
         final SearchGroupsFieldCommandResult fieldCommandResult = fieldCommand.result();
         final Collection<SearchGroup<BytesRef>> searchGroups = fieldCommandResult.getSearchGroups();
         if (searchGroups != null) {
-          commandResult.add("topGroups", serializeSearchGroup(searchGroups, fieldCommand.getGroupSort()));
+          commandResult.add(TOP_GROUPS, serializeSearchGroup(searchGroups, fieldCommand.getGroupSort()));
         }
         final Integer groupedCount = fieldCommandResult.getGroupCount();
         if (groupedCount != null) {
-          commandResult.add("groupCount", groupedCount);
+          commandResult.add(GROUP_COUNT, groupedCount);
         }
       } else {
         continue;
@@ -77,12 +80,12 @@ public class SearchGroupsResultTransform
    */
   @Override
   public Map<String, SearchGroupsFieldCommandResult> transformToNative(NamedList<NamedList> shardResponse, Sort groupSort, Sort sortWithinGroup, String shard) {
-    final Map<String, SearchGroupsFieldCommandResult> result = new HashMap<>();
+    final Map<String, SearchGroupsFieldCommandResult> result = new HashMap<>(shardResponse.size());
     for (Map.Entry<String, NamedList> command : shardResponse) {
       List<SearchGroup<BytesRef>> searchGroups = new ArrayList<>();
       NamedList topGroupsAndGroupCount = command.getValue();
       @SuppressWarnings("unchecked")
-      NamedList<List<Comparable>> rawSearchGroups = (NamedList<List<Comparable>>) topGroupsAndGroupCount.get("topGroups");
+      final NamedList<List<Comparable>> rawSearchGroups = (NamedList<List<Comparable>>) topGroupsAndGroupCount.get(TOP_GROUPS);
       if (rawSearchGroups != null) {
         for (Map.Entry<String, List<Comparable>> rawSearchGroup : rawSearchGroups){
           SearchGroup<BytesRef> searchGroup = new SearchGroup<>();
@@ -101,14 +104,14 @@ public class SearchGroupsResultTransform
         }
       }
 
-      Integer groupCount = (Integer) topGroupsAndGroupCount.get("groupCount");
+      final Integer groupCount = (Integer) topGroupsAndGroupCount.get(GROUP_COUNT);
       result.put(command.getKey(), new SearchGroupsFieldCommandResult(groupCount, searchGroups));
     }
     return result;
   }
 
   private NamedList serializeSearchGroup(Collection<SearchGroup<BytesRef>> data, Sort groupSort) {
-    NamedList<Object[]> result = new NamedList<>();
+    final NamedList<Object[]> result = new NamedList<>(data.size());
 
     for (SearchGroup<BytesRef> searchGroup : data) {
       Object[] convertedSortValues = new Object[searchGroup.sortValues.length];

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java Thu Oct 15 10:25:39 2015
@@ -20,13 +20,10 @@ package org.apache.solr.search.join;
 import java.io.IOException;
 
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.BitsFilteredDocIdSet;
 import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryWrapperFilter;
-import org.apache.lucene.search.join.QueryBitSetProducer;
 import org.apache.lucene.search.join.BitSetProducer;
+import org.apache.lucene.search.join.QueryBitSetProducer;
 import org.apache.lucene.search.join.ScoreMode;
 import org.apache.lucene.search.join.ToParentBlockJoinQuery;
 import org.apache.lucene.util.BitDocIdSet;
@@ -34,6 +31,8 @@ import org.apache.lucene.util.BitSet;
 import org.apache.lucene.util.Bits;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.search.BitsFilteredDocIdSet;
+import org.apache.solr.search.Filter;
 import org.apache.solr.search.QParser;
 import org.apache.solr.search.QueryParsing;
 import org.apache.solr.search.SolrCache;
@@ -96,7 +95,7 @@ class BlockJoinParentQParser extends QPa
   }
 
   private BitSetProducer createParentFilter(Query parentQ) {
-    return new QueryBitSetProducer(new QueryWrapperFilter(parentQ));
+    return new QueryBitSetProducer(parentQ);
   }
 
   // We need this wrapper since BitDocIdSetFilter does not extend Filter

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentDictionaryFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentDictionaryFactory.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentDictionaryFactory.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentDictionaryFactory.java Thu Oct 15 10:25:39 2015
@@ -33,6 +33,8 @@ public class DocumentDictionaryFactory e
   
   public static final String PAYLOAD_FIELD = "payloadField";
 
+  public static final String CONTEXT_FIELD = "contextField";
+
   @Override
   public Dictionary create(SolrCore core, SolrIndexSearcher searcher) {
     if(params == null) {
@@ -42,12 +44,13 @@ public class DocumentDictionaryFactory e
     String field = (String) params.get(FIELD);
     String weightField = (String) params.get(WEIGHT_FIELD);
     String payloadField = (String) params.get(PAYLOAD_FIELD);
-    
+    String contextField = (String) params.get(CONTEXT_FIELD);
+
     if (field == null) {
       throw new IllegalArgumentException(FIELD + " is a mandatory parameter");
     }
 
-    return new DocumentDictionary(searcher.getIndexReader(), field, weightField, payloadField);
+    return new DocumentDictionary(searcher.getIndexReader(), field, weightField, payloadField, contextField);
   }
   
 }

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java Thu Oct 15 10:25:39 2015
@@ -17,7 +17,11 @@ package org.apache.solr.spelling.suggest
  * limitations under the License.
  */
 
+import java.io.IOException;
+import java.nio.file.Paths;
+
 import org.apache.lucene.search.suggest.Lookup;
+import org.apache.lucene.store.FSDirectory;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.spelling.suggest.jaspell.JaspellLookupFactory;
@@ -41,4 +45,23 @@ public abstract class LookupFactory {
    * <b>NOTE:</b> not all {@link Lookup} implementations store in-memory data structures
    * */
   public abstract String storeFileName();
+
+  /** Non-null if this sugggester created a temp dir, needed only during build */
+  private static FSDirectory tmpBuildDir;
+
+  protected static synchronized FSDirectory getTempDir() {
+    if (tmpBuildDir == null) {
+      // Lazy init
+      String tempDirPath = System.getProperty("java.io.tmpdir");
+      if (tempDirPath == null)  {
+        throw new RuntimeException("Java has no temporary folder property (java.io.tmpdir)?");
+      }
+      try {
+        tmpBuildDir = FSDirectory.open(Paths.get(tempDirPath));
+      } catch (IOException ioe) {
+        throw new RuntimeException(ioe);
+      }
+    }
+    return tmpBuildDir;
+  }
 }

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java Thu Oct 15 10:25:39 2015
@@ -23,13 +23,22 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardTokenizerFactory;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Query;
 import org.apache.lucene.search.spell.Dictionary;
 import org.apache.lucene.search.suggest.Lookup;
 import org.apache.lucene.search.suggest.Lookup.LookupResult;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.IOUtils;
+import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.CloseHook;
 import org.apache.solr.core.SolrCore;
@@ -38,6 +47,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.solr.common.params.CommonParams.NAME;
+import static org.apache.solr.spelling.suggest.fst.AnalyzingInfixLookupFactory.CONTEXTS_FIELD_NAME;
 
 /** 
  * Responsible for loading the lookup and dictionary Implementations specified by 
@@ -61,7 +71,7 @@ public class SolrSuggester implements Ac
   
   /** Fully-qualified class of the {@link Dictionary} implementation */
   public static final String DICTIONARY_IMPL = "dictionaryImpl";
-  
+
   /**
    * Name of the location where to persist the dictionary. If this location
    * is relative then the data will be stored under the core's dataDir. If this
@@ -81,8 +91,9 @@ public class SolrSuggester implements Ac
 
   private LookupFactory factory;
   private DictionaryFactory dictionaryFactory;
-  
-  /** 
+  private Analyzer contextFilterQueryAnalyzer;
+
+  /**
    * Uses the <code>config</code> and the <code>core</code> to initialize the underlying 
    * Lucene suggester
    * */
@@ -101,6 +112,9 @@ public class SolrSuggester implements Ac
       lookupImpl = LookupFactory.DEFAULT_FILE_BASED_DICT;
       LOG.info("No " + LOOKUP_IMPL + " parameter was provided falling back to " + lookupImpl);
     }
+
+    contextFilterQueryAnalyzer = new TokenizerChain(new StandardTokenizerFactory(Collections.EMPTY_MAP), null);
+
     // initialize appropriate lookup instance
     factory = core.getResourceLoader().newInstance(lookupImpl, LookupFactory.class);
     lookup = factory.create(config, core);
@@ -146,7 +160,7 @@ public class SolrSuggester implements Ac
         DictionaryFactory.DEFAULT_FILE_BASED_DICT;
       LOG.info("No " + DICTIONARY_IMPL + " parameter was provided falling back to " + dictionaryImpl);
     }
-    
+
     dictionaryFactory = core.getResourceLoader().newInstance(dictionaryImpl, DictionaryFactory.class);
     dictionaryFactory.setParams(config);
     LOG.info("Dictionary loaded with params: " + config);
@@ -212,11 +226,41 @@ public class SolrSuggester implements Ac
     }
     
     SuggesterResult res = new SuggesterResult();
-    List<LookupResult> suggestions = lookup.lookup(options.token, false, options.count);
+    List<LookupResult> suggestions;
+    if(options.contextFilterQuery == null){
+      //TODO: this path needs to be fixed to accept query params to override configs such as allTermsRequired, highlight
+      suggestions = lookup.lookup(options.token, false, options.count);
+    } else {
+      BooleanQuery query = parseContextFilterQuery(options.contextFilterQuery);
+      suggestions = lookup.lookup(options.token, query, options.count, options.allTermsRequired, options.highlight);
+      if(suggestions == null){
+        // Context filtering not supported/configured by lookup
+        // Silently ignore filtering and serve a result by querying without context filtering
+        LOG.debug("Context Filtering Query not supported by {}", lookup.getClass());
+        suggestions = lookup.lookup(options.token, false, options.count);
+      }
+    }
     res.add(getName(), options.token.toString(), suggestions);
     return res;
   }
 
+  private BooleanQuery parseContextFilterQuery(String contextFilter) {
+    if(contextFilter == null){
+      return null;
+    }
+
+    Query query = null;
+    try {
+      query = new StandardQueryParser(contextFilterQueryAnalyzer).parse(contextFilter, CONTEXTS_FIELD_NAME);
+      if (query instanceof BooleanQuery) {
+        return (BooleanQuery) query;
+      }
+      return new BooleanQuery.Builder().add(query, BooleanClause.Occur.MUST).build();
+    } catch (QueryNodeException e) {
+      throw new IllegalArgumentException("Failed to parse query: " + query);
+    }
+  }
+
   /** Returns the unique name of the suggester */
   public String getName() {
     return name;

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterOptions.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterOptions.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterOptions.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterOptions.java Thu Oct 15 10:25:39 2015
@@ -30,9 +30,21 @@ public class SuggesterOptions {
   
   /** Number of suggestions requested */
   int count;
-  
-  public SuggesterOptions(CharsRef token, int count) {
+
+  /** A Solr or Lucene query for filtering suggestions*/
+  String contextFilterQuery;
+
+  /** Are all terms required?*/
+  boolean allTermsRequired;
+
+  /** Highlight term in results?*/
+  boolean highlight;
+
+  public SuggesterOptions(CharsRef token, int count, String contextFilterQuery, boolean allTermsRequired, boolean highlight) {
     this.token = token;
     this.count = count;
+    this.contextFilterQuery = contextFilterQuery;
+    this.allTermsRequired = allTermsRequired;
+    this.highlight = highlight;
   }
 }

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterParams.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterParams.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterParams.java Thu Oct 15 10:25:39 2015
@@ -66,4 +66,21 @@ public interface SuggesterParams {
    * This parameter does not need any suggest dictionary names to be specified
    */
   public static final String SUGGEST_RELOAD_ALL = SUGGEST_PREFIX + "reloadAll";
+
+  /**
+   * contextFilterQuery to use for filtering the result of the suggestion
+   */
+  public static final String SUGGEST_CONTEXT_FILTER_QUERY = SUGGEST_PREFIX + "cfq";
+
+  /**
+   * Whether keyword should be highlighted in result or not
+   */
+  public static final String SUGGEST_HIGHLIGHT = SUGGEST_PREFIX + "highlight";
+
+
+  /**
+   * Whether all terms are required or not
+   */
+  public static final String SUGGEST_ALL_TERMS_REQUIRED = SUGGEST_PREFIX + "allTermsRequired";
+
 }

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java Thu Oct 15 10:25:39 2015
@@ -75,6 +75,11 @@ public class AnalyzingInfixLookupFactory
    * File name for the automaton.
    */
   private static final String FILENAME = "iwfsta.bin";
+
+  /**
+   * Clone of CONTEXTS_FIELD_NAME in AnalyzingInfixSuggester
+   */
+  public static final String CONTEXTS_FIELD_NAME = "contexts";
   
   
   @Override
@@ -110,7 +115,7 @@ public class AnalyzingInfixLookupFactory
     
     boolean highlight = params.get(HIGHLIGHT) != null
     ? Boolean.getBoolean(params.get(HIGHLIGHT).toString())
-    : AnalyzingInfixSuggester.DEFAULT_HIGHLIGHT; 
+    : AnalyzingInfixSuggester.DEFAULT_HIGHLIGHT;
 
     try {
       return new AnalyzingInfixSuggester(FSDirectory.open(new File(indexPath).toPath()), indexAnalyzer,

Modified: lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java?rev=1708778&r1=1708777&r2=1708778&view=diff
==============================================================================
--- lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java (original)
+++ lucene/dev/branches/lucene6825/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java Thu Oct 15 10:25:39 2015
@@ -120,8 +120,7 @@ public class AnalyzingLookupFactory exte
     ? Boolean.valueOf(params.get(PRESERVE_POSITION_INCREMENTS).toString())
     : false;
 
-    
-    return new AnalyzingSuggester(indexAnalyzer, queryAnalyzer, flags, maxSurfaceFormsPerAnalyzedForm,
+    return new AnalyzingSuggester(getTempDir(), "suggester", indexAnalyzer, queryAnalyzer, flags, maxSurfaceFormsPerAnalyzedForm,
         maxGraphExpansions, preservePositionIncrements);
   }