You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by is...@apache.org on 2017/03/19 15:57:41 UTC

[07/12] lucene-solr:jira/solr-6736: Merge master into jira/solr-6736 branch

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
index 3a4c3fe..f4abee0 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
@@ -38,6 +38,7 @@ import java.util.regex.PatternSyntaxException;
 import java.util.stream.Collectors;
 
 import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Histogram;
 import com.codahale.metrics.Meter;
 import com.codahale.metrics.Metric;
@@ -520,7 +521,9 @@ public class SolrMetricManager {
     }
   }
 
-
+  public void registerGauge(String registry, Gauge<?> gauge, boolean force, String metricName, String... metricPath) {
+    register(registry, gauge, force, metricName, metricPath);
+  }
 
   /**
    * This method creates a hierarchical name with arbitrary levels of hierarchy

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
index 846e805..0c3b651 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
@@ -106,10 +106,12 @@ public class SolrClusterReporter extends SolrMetricReporter {
           add("os\\.FreeSwapSpaceSize");
           add("os\\.OpenFileDescriptorCount");
           add("threads\\.count");
-        }})); // all metrics
-    // XXX anything interesting here?
-    //add(new SolrReporter.Specification(OVERSEER_GROUP, "node", SolrMetricManager.overridableRegistryName(SolrInfoMBean.Group.node.toString()),
-    //    Collections.emptySet())); // all metrics
+        }}));
+    add(new SolrReporter.Report(CLUSTER_GROUP, "node", SolrMetricManager.overridableRegistryName(SolrInfoMBean.Group.node.toString()),
+        new HashSet<String>() {{
+          add("CONTAINER\\.cores\\..*");
+          add("CONTAINER\\.fs\\..*");
+        }}));
     add(new SolrReporter.Report(CLUSTER_GROUP, "leader.$1", "solr\\.collection\\.(.*)\\.leader",
         new HashSet<String>(){{
           add("UPDATE\\./update/.*");

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
index e9b8c3d..0bca68f 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
@@ -361,7 +361,7 @@ public class SolrReporter extends ScheduledReporter {
         }
         final String effectiveGroup = group;
         MetricUtils.toSolrInputDocuments(metricManager.registry(registryName), Collections.singletonList(report.filter), MetricFilter.ALL,
-            skipHistograms, skipAggregateValues, metadata, doc -> {
+            skipHistograms, skipAggregateValues, false, metadata, doc -> {
               doc.setField(REGISTRY_ID, registryName);
               doc.setField(GROUP_ID, effectiveGroup);
               if (effectiveLabel != null) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
index 2b20274..8b36d3e 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
@@ -61,9 +61,10 @@ public class SolrShardReporter extends SolrMetricReporter {
 
   public static final List<String> DEFAULT_FILTERS = new ArrayList(){{
     add("TLOG.*");
+    add("CORE\\.fs.*");
     add("REPLICATION.*");
-    add("INDEX.flush.*");
-    add("INDEX.merge.major.*");
+    add("INDEX\\.flush.*");
+    add("INDEX\\.merge\\.major.*");
     add("UPDATE\\./update/.*requests");
     add("QUERY\\./select.*requests");
   }};

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/parser/QueryParser.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.java b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
index 42f359e..d9a64f4 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.java
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
@@ -3,13 +3,17 @@ package org.apache.solr.parser;
 
 import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.util.Version;
-import org.apache.solr.search.QParser;
 import org.apache.solr.search.SyntaxError;
+import org.apache.solr.search.QParser;
+import org.apache.solr.search.QueryParserConfigurationException;
 
 
 public class QueryParser extends SolrQueryParserBase implements QueryParserConstants {
@@ -17,9 +21,44 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
    */
   static public enum Operator { OR, AND }
 
-   public QueryParser(Version matchVersion, String defaultField, QParser parser) {
+  /** default split on whitespace behavior */
+  public static final boolean DEFAULT_SPLIT_ON_WHITESPACE = true;
+
+   public QueryParser(String defaultField, QParser parser) {
     this(new FastCharStream(new StringReader("")));
-    init(matchVersion, defaultField, parser);
+    init(defaultField, parser);
+  }
+
+  /**
+   * @see #setSplitOnWhitespace(boolean)
+   */
+  public boolean getSplitOnWhitespace() {
+    return splitOnWhitespace;
+  }
+
+  /**
+   * Whether query text should be split on whitespace prior to analysis.
+   * Default is <code>{@value #DEFAULT_SPLIT_ON_WHITESPACE}</code>.
+   */
+  public void setSplitOnWhitespace(boolean splitOnWhitespace) {
+    this.splitOnWhitespace = splitOnWhitespace;
+  }
+
+  private boolean splitOnWhitespace = DEFAULT_SPLIT_ON_WHITESPACE;
+  private static Set<Integer> disallowedPostMultiTerm
+    = new HashSet<Integer>(Arrays.asList(COLON, STAR, FUZZY_SLOP, CARAT, AND, OR));
+  private static boolean allowedPostMultiTerm(int tokenKind) {
+    return disallowedPostMultiTerm.contains(tokenKind) == false;
+  }
+
+  @Override
+  protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
+                                boolean quoted, boolean fieldAutoGenPhraseQueries) throws SyntaxError {
+    if ((getAutoGeneratePhraseQueries() || fieldAutoGenPhraseQueries) && splitOnWhitespace == false) {
+      throw new QueryParserConfigurationException
+          ("Field '" + field + "': autoGeneratePhraseQueries == true is disallowed when sow/splitOnWhitespace == false");
+    }
+    return super.newFieldQuery(analyzer, field, queryText, quoted, fieldAutoGenPhraseQueries);
   }
 
 // *   Query  ::= ( Clause )*
@@ -96,13 +135,38 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
 
   final public Query Query(String field) throws ParseException, SyntaxError {
   List<BooleanClause> clauses = new ArrayList<BooleanClause>();
-  Query q, firstQuery=null;
+  Query q;
   int conj, mods;
-    mods = Modifiers();
-    q = Clause(field);
-    addClause(clauses, CONJ_NONE, mods, q);
-    if (mods == MOD_NONE)
-        firstQuery=q;
+    if (jj_2_1(2)) {
+      MultiTerm(field, clauses);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case NOT:
+      case PLUS:
+      case MINUS:
+      case BAREOPER:
+      case LPAREN:
+      case STAR:
+      case QUOTED:
+      case TERM:
+      case PREFIXTERM:
+      case WILDTERM:
+      case REGEXPTERM:
+      case RANGEIN_START:
+      case RANGEEX_START:
+      case LPARAMS:
+      case FILTER:
+      case NUMBER:
+        mods = Modifiers();
+        q = Clause(field);
+        addClause(clauses, CONJ_NONE, mods, q);
+        break;
+      default:
+        jj_la1[4] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
     label_1:
     while (true) {
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -127,19 +191,50 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         ;
         break;
       default:
-        jj_la1[4] = jj_gen;
+        jj_la1[5] = jj_gen;
         break label_1;
       }
-      conj = Conjunction();
-      mods = Modifiers();
-      q = Clause(field);
-      addClause(clauses, conj, mods, q);
+      if (jj_2_2(2)) {
+        MultiTerm(field, clauses);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case AND:
+        case OR:
+        case NOT:
+        case PLUS:
+        case MINUS:
+        case BAREOPER:
+        case LPAREN:
+        case STAR:
+        case QUOTED:
+        case TERM:
+        case PREFIXTERM:
+        case WILDTERM:
+        case REGEXPTERM:
+        case RANGEIN_START:
+        case RANGEEX_START:
+        case LPARAMS:
+        case FILTER:
+        case NUMBER:
+          conj = Conjunction();
+          mods = Modifiers();
+          q = Clause(field);
+        addClause(clauses, conj, mods, q);
+          break;
+        default:
+          jj_la1[6] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
     }
-      if (clauses.size() == 1 && firstQuery != null)
+    if (clauses.size() == 1 && clauses.get(0).getOccur() == BooleanClause.Occur.SHOULD) {
+      Query firstQuery = clauses.get(0).getQuery();
+      if ( ! (firstQuery instanceof RawQuery) || ((RawQuery)firstQuery).getTermCount() == 1) {
         {if (true) return rawToNormal(firstQuery);}
-      else {
-        {if (true) return getBooleanQuery(clauses);}
       }
+    }
+    {if (true) return getBooleanQuery(clauses);}
     throw new Error("Missing return statement in function");
   }
 
@@ -148,20 +243,20 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
   Token fieldToken=null, boost=null;
   Token localParams=null;
   int flags = 0;
-    if (jj_2_1(2)) {
+    if (jj_2_3(2)) {
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case TERM:
         fieldToken = jj_consume_token(TERM);
         jj_consume_token(COLON);
-                               field=discardEscapeChar(fieldToken.image);
+                                  field = discardEscapeChar(fieldToken.image);
         break;
       case STAR:
         jj_consume_token(STAR);
         jj_consume_token(COLON);
-                      field="*";
+                         field = "*";
         break;
       default:
-        jj_la1[5] = jj_gen;
+        jj_la1[7] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
@@ -191,7 +286,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         boost = jj_consume_token(NUMBER);
         break;
       default:
-        jj_la1[6] = jj_gen;
+        jj_la1[8] = jj_gen;
         ;
       }
       break;
@@ -206,10 +301,10 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         boost = jj_consume_token(NUMBER);
         break;
       default:
-        jj_la1[7] = jj_gen;
+        jj_la1[9] = jj_gen;
         ;
       }
-                                                                                            q=getFilter(q); restoreFlags(flags);
+                                                                                             q=getFilter(q); restoreFlags(flags);
       break;
     case LPARAMS:
       localParams = jj_consume_token(LPARAMS);
@@ -219,17 +314,17 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         boost = jj_consume_token(NUMBER);
         break;
       default:
-        jj_la1[8] = jj_gen;
+        jj_la1[10] = jj_gen;
         ;
       }
-                                                          q=getLocalParams(field, localParams.image);
+                                                           q=getLocalParams(field, localParams.image);
       break;
     default:
-      jj_la1[9] = jj_gen;
+      jj_la1[11] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
     }
-       {if (true) return handleBoost(q, boost);}
+    {if (true) return handleBoost(q, boost);}
     throw new Error("Missing return statement in function");
   }
 
@@ -278,35 +373,48 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
                           term.image = term.image.substring(0,1);
         break;
       default:
-        jj_la1[10] = jj_gen;
+        jj_la1[12] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case FUZZY_SLOP:
-        fuzzySlop = jj_consume_token(FUZZY_SLOP);
-                               fuzzy=true;
-        break;
-      default:
-        jj_la1[11] = jj_gen;
-        ;
-      }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case CARAT:
-        jj_consume_token(CARAT);
-        boost = jj_consume_token(NUMBER);
+      case FUZZY_SLOP:
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case CARAT:
+          jj_consume_token(CARAT);
+          boost = jj_consume_token(NUMBER);
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case FUZZY_SLOP:
+            fuzzySlop = jj_consume_token(FUZZY_SLOP);
+                                                        fuzzy=true;
+            break;
+          default:
+            jj_la1[13] = jj_gen;
+            ;
+          }
+          break;
         case FUZZY_SLOP:
           fuzzySlop = jj_consume_token(FUZZY_SLOP);
-                                                        fuzzy=true;
+                                 fuzzy=true;
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case CARAT:
+            jj_consume_token(CARAT);
+            boost = jj_consume_token(NUMBER);
+            break;
+          default:
+            jj_la1[14] = jj_gen;
+            ;
+          }
           break;
         default:
-          jj_la1[12] = jj_gen;
-          ;
+          jj_la1[15] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
         }
         break;
       default:
-        jj_la1[13] = jj_gen;
+        jj_la1[16] = jj_gen;
         ;
       }
       q = handleBareTokenQuery(getField(field), term, fuzzySlop, prefix, wildcard, fuzzy, regexp);
@@ -316,13 +424,13 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case RANGEIN_START:
         jj_consume_token(RANGEIN_START);
-                           startInc=true;
+                        startInc = true;
         break;
       case RANGEEX_START:
         jj_consume_token(RANGEEX_START);
         break;
       default:
-        jj_la1[14] = jj_gen;
+        jj_la1[17] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
@@ -334,7 +442,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         goop1 = jj_consume_token(RANGE_QUOTED);
         break;
       default:
-        jj_la1[15] = jj_gen;
+        jj_la1[18] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
@@ -343,7 +451,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         jj_consume_token(RANGE_TO);
         break;
       default:
-        jj_la1[16] = jj_gen;
+        jj_la1[19] = jj_gen;
         ;
       }
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -354,20 +462,20 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         goop2 = jj_consume_token(RANGE_QUOTED);
         break;
       default:
-        jj_la1[17] = jj_gen;
+        jj_la1[20] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case RANGEIN_END:
         jj_consume_token(RANGEIN_END);
-                         endInc=true;
+                      endInc = true;
         break;
       case RANGEEX_END:
         jj_consume_token(RANGEEX_END);
         break;
       default:
-        jj_la1[18] = jj_gen;
+        jj_la1[21] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
@@ -377,46 +485,71 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
         boost = jj_consume_token(NUMBER);
         break;
       default:
-        jj_la1[19] = jj_gen;
+        jj_la1[22] = jj_gen;
         ;
       }
-         boolean startOpen=false;
-         boolean endOpen=false;
-         if (goop1.kind == RANGE_QUOTED) {
-           goop1.image = goop1.image.substring(1, goop1.image.length()-1);
-         } else if ("*".equals(goop1.image)) {
-           startOpen=true;
-         }
-         if (goop2.kind == RANGE_QUOTED) {
-           goop2.image = goop2.image.substring(1, goop2.image.length()-1);
-         } else if ("*".equals(goop2.image)) {
-           endOpen=true;
-         }
-         q = getRangeQuery(getField(field), startOpen ? null : discardEscapeChar(goop1.image), endOpen ? null : discardEscapeChar(goop2.image), startInc, endInc);
+      boolean startOpen=false;
+      boolean endOpen=false;
+      if (goop1.kind == RANGE_QUOTED) {
+        goop1.image = goop1.image.substring(1, goop1.image.length()-1);
+      } else if ("*".equals(goop1.image)) {
+        startOpen=true;
+      }
+      if (goop2.kind == RANGE_QUOTED) {
+        goop2.image = goop2.image.substring(1, goop2.image.length()-1);
+      } else if ("*".equals(goop2.image)) {
+        endOpen=true;
+      }
+      q = getRangeQuery(getField(field),
+                        startOpen ? null : discardEscapeChar(goop1.image),
+                        endOpen ? null : discardEscapeChar(goop2.image), startInc, endInc);
       break;
     case QUOTED:
       term = jj_consume_token(QUOTED);
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case FUZZY_SLOP:
-        fuzzySlop = jj_consume_token(FUZZY_SLOP);
-        break;
-      default:
-        jj_la1[20] = jj_gen;
-        ;
-      }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case CARAT:
-        jj_consume_token(CARAT);
-        boost = jj_consume_token(NUMBER);
+      case FUZZY_SLOP:
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case CARAT:
+          jj_consume_token(CARAT);
+          boost = jj_consume_token(NUMBER);
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case FUZZY_SLOP:
+            fuzzySlop = jj_consume_token(FUZZY_SLOP);
+                                                        fuzzy=true;
+            break;
+          default:
+            jj_la1[23] = jj_gen;
+            ;
+          }
+          break;
+        case FUZZY_SLOP:
+          fuzzySlop = jj_consume_token(FUZZY_SLOP);
+                                 fuzzy=true;
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case CARAT:
+            jj_consume_token(CARAT);
+            boost = jj_consume_token(NUMBER);
+            break;
+          default:
+            jj_la1[24] = jj_gen;
+            ;
+          }
+          break;
+        default:
+          jj_la1[25] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
         break;
       default:
-        jj_la1[21] = jj_gen;
+        jj_la1[26] = jj_gen;
         ;
       }
-        q = handleQuotedTerm(getField(field), term, fuzzySlop);
+      q = handleQuotedTerm(getField(field), term, fuzzySlop);
       break;
     default:
-      jj_la1[22] = jj_gen;
+      jj_la1[27] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
     }
@@ -424,6 +557,44 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
     throw new Error("Missing return statement in function");
   }
 
+  final public void MultiTerm(String field, List<BooleanClause> clauses) throws ParseException, SyntaxError {
+  Token text;
+  List<String> terms = null;
+    text = jj_consume_token(TERM);
+    if (splitOnWhitespace) {
+      Query q = getFieldQuery(getField(field), discardEscapeChar(text.image), false, true);
+      addClause(clauses, CONJ_NONE, MOD_NONE, q);
+    } else {
+      terms = new ArrayList<String>();
+      terms.add(discardEscapeChar(text.image));
+    }
+    if (getToken(1).kind == TERM && allowedPostMultiTerm(getToken(2).kind)) {
+
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    label_2:
+    while (true) {
+      text = jj_consume_token(TERM);
+      if (splitOnWhitespace) {
+        Query q = getFieldQuery(getField(field), discardEscapeChar(text.image), false, true);
+        addClause(clauses, CONJ_NONE, MOD_NONE, q);
+      } else {
+        terms.add(discardEscapeChar(text.image));
+      }
+      if (getToken(1).kind == TERM && allowedPostMultiTerm(getToken(2).kind)) {
+        ;
+      } else {
+        break label_2;
+      }
+    }
+    if (splitOnWhitespace == false) {
+      Query q = getFieldQuery(getField(field), terms, true);
+      addMultiTermClause(clauses, q);
+    }
+  }
+
   private boolean jj_2_1(int xla) {
     jj_la = xla; jj_lastpos = jj_scanpos = token;
     try { return !jj_3_1(); }
@@ -431,28 +602,76 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
     finally { jj_save(0, xla); }
   }
 
-  private boolean jj_3R_3() {
-    if (jj_scan_token(STAR)) return true;
-    if (jj_scan_token(COLON)) return true;
+  private boolean jj_2_2(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_2(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(1, xla); }
+  }
+
+  private boolean jj_2_3(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_3(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(2, xla); }
+  }
+
+  private boolean jj_3R_7() {
+    if (jj_scan_token(TERM)) return true;
     return false;
   }
 
-  private boolean jj_3R_2() {
+  private boolean jj_3R_4() {
     if (jj_scan_token(TERM)) return true;
     if (jj_scan_token(COLON)) return true;
     return false;
   }
 
   private boolean jj_3_1() {
+    if (jj_3R_3()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_6() {
+    return false;
+  }
+
+  private boolean jj_3R_3() {
+    if (jj_scan_token(TERM)) return true;
+    jj_lookingAhead = true;
+    jj_semLA = getToken(1).kind == TERM && allowedPostMultiTerm(getToken(2).kind);
+    jj_lookingAhead = false;
+    if (!jj_semLA || jj_3R_6()) return true;
+    Token xsp;
+    if (jj_3R_7()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_7()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3_3() {
     Token xsp;
     xsp = jj_scanpos;
-    if (jj_3R_2()) {
+    if (jj_3R_4()) {
     jj_scanpos = xsp;
-    if (jj_3R_3()) return true;
+    if (jj_3R_5()) return true;
     }
     return false;
   }
 
+  private boolean jj_3_2() {
+    if (jj_3R_3()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_5() {
+    if (jj_scan_token(STAR)) return true;
+    if (jj_scan_token(COLON)) return true;
+    return false;
+  }
+
   /** Generated Token Manager. */
   public QueryParserTokenManager token_source;
   /** Current token. */
@@ -462,8 +681,11 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
   private int jj_ntk;
   private Token jj_scanpos, jj_lastpos;
   private int jj_la;
+  /** Whether we are looking ahead. */
+  private boolean jj_lookingAhead = false;
+  private boolean jj_semLA;
   private int jj_gen;
-  final private int[] jj_la1 = new int[23];
+  final private int[] jj_la1 = new int[28];
   static private int[] jj_la1_0;
   static private int[] jj_la1_1;
   static {
@@ -471,12 +693,12 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
       jj_la1_init_1();
    }
    private static void jj_la1_init_0() {
-      jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x4000000,0x800000,0xc0000000,0x0,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0xfb440000,};
+      jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4f8000,0xfb4fe000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x800000,0x4800000,0x4800000,0xc0000000,0x0,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0x4800000,0x4800000,0xfb440000,};
    }
    private static void jj_la1_init_1() {
-      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0xc0,0x8,0xc0,0x30,0x0,0x0,0x0,0x4,};
+      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x7,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0x0,0xc0,0x8,0xc0,0x30,0x0,0x0,0x0,0x0,0x0,0x4,};
    }
-  final private JJCalls[] jj_2_rtns = new JJCalls[1];
+  final private JJCalls[] jj_2_rtns = new JJCalls[3];
   private boolean jj_rescan = false;
   private int jj_gc = 0;
 
@@ -486,7 +708,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 23; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 28; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -495,8 +717,9 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
     token_source.ReInit(stream);
     token = new Token();
     jj_ntk = -1;
+    jj_lookingAhead = false;
     jj_gen = 0;
-    for (int i = 0; i < 23; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 28; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -506,7 +729,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 23; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 28; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -516,7 +739,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 23; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 28; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -579,7 +802,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
 
 /** Get the specific Token. */
   final public Token getToken(int index) {
-    Token t = token;
+    Token t = jj_lookingAhead ? jj_scanpos : token;
     for (int i = 0; i < index; i++) {
       if (t.next != null) t = t.next;
       else t = t.next = token_source.getNextToken();
@@ -633,7 +856,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
       la1tokens[jj_kind] = true;
       jj_kind = -1;
     }
-    for (int i = 0; i < 23; i++) {
+    for (int i = 0; i < 28; i++) {
       if (jj_la1[i] == jj_gen) {
         for (int j = 0; j < 32; j++) {
           if ((jj_la1_0[i] & (1<<j)) != 0) {
@@ -672,7 +895,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
 
   private void jj_rescan_token() {
     jj_rescan = true;
-    for (int i = 0; i < 1; i++) {
+    for (int i = 0; i < 3; i++) {
     try {
       JJCalls p = jj_2_rtns[i];
       do {
@@ -680,6 +903,8 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
           jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
           switch (i) {
             case 0: jj_3_1(); break;
+            case 1: jj_3_2(); break;
+            case 2: jj_3_3(); break;
           }
         }
         p = p.next;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
index a6b93ca..5eb4ec7 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
@@ -27,18 +27,17 @@ package org.apache.solr.parser;
 
 import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Locale;
+import java.util.Set;
 
 import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.document.DateTools;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermRangeQuery;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.util.Version;
 import org.apache.solr.search.SyntaxError;
 import org.apache.solr.search.QParser;
+import org.apache.solr.search.QueryParserConfigurationException;
 
 
 public class QueryParser extends SolrQueryParserBase {
@@ -46,9 +45,44 @@ public class QueryParser extends SolrQueryParserBase {
    */
   static public enum Operator { OR, AND }
 
-   public QueryParser(Version matchVersion, String defaultField, QParser parser) {
+  /** default split on whitespace behavior */
+  public static final boolean DEFAULT_SPLIT_ON_WHITESPACE = true;
+
+   public QueryParser(String defaultField, QParser parser) {
     this(new FastCharStream(new StringReader("")));
-    init(matchVersion, defaultField, parser);
+    init(defaultField, parser);
+  }
+
+  /**
+   * @see #setSplitOnWhitespace(boolean)
+   */
+  public boolean getSplitOnWhitespace() {
+    return splitOnWhitespace;
+  }
+
+  /**
+   * Whether query text should be split on whitespace prior to analysis.
+   * Default is <code>{@value #DEFAULT_SPLIT_ON_WHITESPACE}</code>.
+   */
+  public void setSplitOnWhitespace(boolean splitOnWhitespace) {
+    this.splitOnWhitespace = splitOnWhitespace;
+  }
+
+  private boolean splitOnWhitespace = DEFAULT_SPLIT_ON_WHITESPACE;
+  private static Set<Integer> disallowedPostMultiTerm
+    = new HashSet<Integer>(Arrays.asList(COLON, STAR, FUZZY_SLOP, CARAT, AND, OR));
+  private static boolean allowedPostMultiTerm(int tokenKind) {
+    return disallowedPostMultiTerm.contains(tokenKind) == false;
+  }
+
+  @Override
+  protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
+                                boolean quoted, boolean fieldAutoGenPhraseQueries) throws SyntaxError {
+    if ((getAutoGeneratePhraseQueries() || fieldAutoGenPhraseQueries) && splitOnWhitespace == false) {
+      throw new QueryParserConfigurationException
+          ("Field '" + field + "': autoGeneratePhraseQueries == true is disallowed when sow/splitOnWhitespace == false");
+    }
+    return super.newFieldQuery(analyzer, field, queryText, quoted, fieldAutoGenPhraseQueries);
   }
 }
 
@@ -63,17 +97,15 @@ TOKEN_MGR_DECLS : {
 /* ***************** */
 
 <*> TOKEN : {
-  <#_NUM_CHAR:   ["0"-"9"] >
- // every character that follows a backslash is considered as an escaped character
- | <#_ESCAPED_CHAR: "\\" ~[] >
- | <#_TERM_START_CHAR: ( ~[ " ", "\t", "\n", "\r", "\u3000", "+", "-", "!", "(", ")", ":", "^",
-                      "[", "]", "\"", "{", "}", "~", "*", "?", "\\", "/" ]
-                      | <_ESCAPED_CHAR> ) >
- | <#_TERM_CHAR: ( <_TERM_START_CHAR>
-                       | <_ESCAPED_CHAR> | "-" | "+" | "/" | "!") >
- | <#_WHITESPACE:  ( " " | "\t" | "\n" | "\r" | "\u3000") >
- | <#_QUOTED_CHAR:  ( ~[ "\"", "\\" ] | <_ESCAPED_CHAR> ) >
- | <#_SQUOTED_CHAR:  ( ~[ "'", "\\" ] | <_ESCAPED_CHAR> ) >
+  <#_NUM_CHAR:        ["0"-"9"] >
+| <#_ESCAPED_CHAR:    "\\" ~[] >  // every character that follows a backslash is considered as an escaped character
+| <#_TERM_START_CHAR: ( ~[ " ", "\t", "\n", "\r", "\u3000", "+", "-", "!", "(", ")", ":", "^",
+                           "[", "]", "\"", "{", "}", "~", "*", "?", "\\", "/" ]
+                        | <_ESCAPED_CHAR> ) >
+| <#_TERM_CHAR:       ( <_TERM_START_CHAR> | <_ESCAPED_CHAR> | "-" | "+" | "/" | "!") >
+| <#_WHITESPACE:      ( " " | "\t" | "\n" | "\r" | "\u3000") >
+| <#_QUOTED_CHAR:     ( ~[ "\"", "\\" ] | <_ESCAPED_CHAR> ) >
+| <#_SQUOTED_CHAR:    ( ~[ "'", "\\" ] | <_ESCAPED_CHAR> ) >
 }
 
 <DEFAULT, COMMENT> SKIP : {
@@ -93,44 +125,43 @@ TOKEN_MGR_DECLS : {
   < <_WHITESPACE>>
 }
 
-
 <DEFAULT> TOKEN : {
-  <AND:       ("AND" | "&&") >
- | <OR:        ("OR" | "||") >
- | <NOT:       ("NOT" | "!") >
- | <PLUS:      "+" >
- | <MINUS:     "-" >
- | <BAREOPER:    ("+"|"-"|"!") <_WHITESPACE> >
- | <LPAREN:    "(" >
- | <RPAREN:    ")" >
- | <COLON:     ":" >
- | <STAR:      "*" >
- | <CARAT:     "^" > : Boost
- | <QUOTED:     "\"" (<_QUOTED_CHAR>)* "\"">
- | <TERM:      <_TERM_START_CHAR> (<_TERM_CHAR>)*  >
- | <FUZZY_SLOP:     "~" ( (<_NUM_CHAR>)+ ( "." (<_NUM_CHAR>)+ )? )? >
- | <PREFIXTERM:  ("*") | ( <_TERM_START_CHAR> (<_TERM_CHAR>)* "*" ) >
- | <WILDTERM:  (<_TERM_START_CHAR> | [ "*", "?" ]) (<_TERM_CHAR> | ( [ "*", "?" ] ))* >
- | <REGEXPTERM: "/" (~["*","/"] | "\\/" ) (~[ "/" ] | "\\/" )* "/" >
- | <RANGEIN_START: "[" > : Range
- | <RANGEEX_START: "{" > : Range
+  <AND:           ("AND" | "&&") >
+| <OR:            ("OR" | "||") >
+| <NOT:           ("NOT" | "!") >
+| <PLUS:          "+" >
+| <MINUS:         "-" >
+| <BAREOPER:      ("+"|"-"|"!") <_WHITESPACE> >
+| <LPAREN:        "(" >
+| <RPAREN:        ")" >
+| <COLON:         ":" >
+| <STAR:          "*" >
+| <CARAT:         "^" > : Boost
+| <QUOTED:        "\"" (<_QUOTED_CHAR>)* "\"">
+| <TERM:          <_TERM_START_CHAR> (<_TERM_CHAR>)*  >
+| <FUZZY_SLOP:    "~" ( (<_NUM_CHAR>)+ ( "." (<_NUM_CHAR>)+ )? )? >
+| <PREFIXTERM:    ("*") | ( <_TERM_START_CHAR> (<_TERM_CHAR>)* "*" ) >
+| <WILDTERM:      (<_TERM_START_CHAR> | [ "*", "?" ]) (<_TERM_CHAR> | ( [ "*", "?" ] ))* >
+| <REGEXPTERM:    "/" (~["*","/"] | "\\/" ) (~[ "/" ] | "\\/" )* "/" >
+| <RANGEIN_START: "[" > : Range
+| <RANGEEX_START: "{" > : Range
 // TODO: consider using token states instead of inlining SQUOTED
-//  | <SQUOTED:     "'" (<_SQUOTED_CHAR>)* "'">
-//  | <LPARAMS:     ("{!" ( (<_WHITESPACE>)* (~["=","}"])+ ( "=" (<QUOTED> | <SQUOTED> | (~[" ","}"])+ )? )? )* "}")+  (~[")"," ","\t","\n","{","^"])*  >
-  | <LPARAMS:     ("{!" ( (<_WHITESPACE>)* (~["=","}"])+ ( "=" (<QUOTED> | ("'" (<_SQUOTED_CHAR>)* "'") | (~[" ","}"])+ )? )? )* "}")+  (~[")"," ","\t","\n","{","^"])*  >
-  | <FILTER:      "filter(" >
+// | <SQUOTED:       "'" (<_SQUOTED_CHAR>)* "'">
+// | <LPARAMS:       ("{!" ( (<_WHITESPACE>)* (~["=","}"])+ ( "=" (<QUOTED> | <SQUOTED> | (~[" ","}"])+ )? )? )* "}")+  (~[")"," ","\t","\n","{","^"])*  >
+| <LPARAMS:       ("{!" ( (<_WHITESPACE>)* (~["=","}"])+ ( "=" (<QUOTED> | ("'" (<_SQUOTED_CHAR>)* "'") | (~[" ","}"])+ )? )? )* "}")+  (~[")"," ","\t","\n","{","^"])*  >
+| <FILTER:        "filter(" >
 }
 
 <Boost> TOKEN : {
- <NUMBER:    ("=")?("-")? (<_NUM_CHAR>)+ ( "." (<_NUM_CHAR>)+ )? > : DEFAULT
+  <NUMBER: ("=")?("-")? (<_NUM_CHAR>)+ ( "." (<_NUM_CHAR>)+ )? > : DEFAULT
 }
 
 <Range> TOKEN : {
- <RANGE_TO: "TO">
- | <RANGEIN_END: "]"> : DEFAULT
- | <RANGEEX_END: "}"> : DEFAULT
- | <RANGE_QUOTED: "\"" (~["\""] | "\\\"")+ "\"">
- | <RANGE_GOOP: (~[ " ", "]", "}" ])+ >
+  <RANGE_TO:     "TO">
+| <RANGEIN_END:  "]"> : DEFAULT
+| <RANGEEX_END:  "}"> : DEFAULT
+| <RANGE_QUOTED: "\"" (~["\""] | "\\\"")+ "\"">
+| <RANGE_GOOP:   (~[ " ", "]", "}" ])+ >
 }
 
 // *   Query  ::= ( Clause )*
@@ -160,8 +191,7 @@ int Modifiers() : {
 }
 
 // This makes sure that there is no garbage after the query string
-Query TopLevelQuery(String field) throws SyntaxError :
-{
+Query TopLevelQuery(String field) throws SyntaxError : {
   Query q;
 }
 {
@@ -174,27 +204,31 @@ Query TopLevelQuery(String field) throws SyntaxError :
 Query Query(String field) throws SyntaxError :
 {
   List<BooleanClause> clauses = new ArrayList<BooleanClause>();
-  Query q, firstQuery=null;
+  Query q;
   int conj, mods;
 }
 {
-  mods=Modifiers() q=Clause(field)
-  {
-    addClause(clauses, CONJ_NONE, mods, q);
-    if (mods == MOD_NONE)
-        firstQuery=q;
-  }
   (
-    conj=Conjunction() mods=Modifiers() q=Clause(field)
-    { addClause(clauses, conj, mods, q); }
+    LOOKAHEAD(2)
+    MultiTerm(field, clauses)
+    | mods=Modifiers() q=Clause(field)
+      { addClause(clauses, CONJ_NONE, mods, q); }
+  )
+  (
+    LOOKAHEAD(2)
+    MultiTerm(field, clauses)
+    | conj=Conjunction() mods=Modifiers() q=Clause(field)
+      { addClause(clauses, conj, mods, q); }
   )*
-    {
-      if (clauses.size() == 1 && firstQuery != null)
+  {
+    if (clauses.size() == 1 && clauses.get(0).getOccur() == BooleanClause.Occur.SHOULD) {
+      Query firstQuery = clauses.get(0).getQuery();
+      if ( ! (firstQuery instanceof RawQuery) || ((RawQuery)firstQuery).getTermCount() == 1) {
         return rawToNormal(firstQuery);
-      else {
-        return getBooleanQuery(clauses);
       }
     }
+    return getBooleanQuery(clauses);
+  }
 }
 
 Query Clause(String field) throws SyntaxError : {
@@ -204,26 +238,22 @@ Query Clause(String field) throws SyntaxError : {
   int flags = 0;
 }
 {
- 
   [
     LOOKAHEAD(2)
     (
-    fieldToken=<TERM> <COLON> {field=discardEscapeChar(fieldToken.image);}
-    | <STAR> <COLON> {field="*";}
+      fieldToken=<TERM> <COLON> { field = discardEscapeChar(fieldToken.image); }
+      | <STAR> <COLON> { field = "*"; }
     )
   ]
-
-
   (
    q=Term(field)
-   | <LPAREN> q=Query(field) <RPAREN> (<CARAT> boost=<NUMBER>)?
-   | (<FILTER> { flags=startFilter(); } q=Query(field) <RPAREN> (<CARAT> boost=<NUMBER>)? { q=getFilter(q); restoreFlags(flags); } )
-   | (localParams = <LPARAMS> (<CARAT> boost=<NUMBER>)? { q=getLocalParams(field, localParams.image); }  )
+   | <LPAREN> q=Query(field) <RPAREN> [ <CARAT> boost=<NUMBER> ]
+   | (<FILTER> { flags=startFilter(); } q=Query(field) <RPAREN> [ <CARAT> boost=<NUMBER> ] { q=getFilter(q); restoreFlags(flags); } )
+   | (localParams = <LPARAMS> [ <CARAT> boost=<NUMBER> ] { q=getLocalParams(field, localParams.image); }  )
   )
-    {  return handleBoost(q, boost); }
+  { return handleBoost(q, boost); }
 }
 
-
 Query Term(String field) throws SyntaxError : {
   Token term, boost=null, fuzzySlop=null, goop1, goop2;
   boolean prefix = false;
@@ -245,40 +275,78 @@ Query Term(String field) throws SyntaxError : {
       | term=<NUMBER>
       | term=<BAREOPER> { term.image = term.image.substring(0,1); }
     )
-    [ fuzzySlop=<FUZZY_SLOP> { fuzzy=true; } ]
-    [ <CARAT> boost=<NUMBER> [ fuzzySlop=<FUZZY_SLOP> { fuzzy=true; } ] ]
+    [
+      <CARAT> boost=<NUMBER> [ fuzzySlop=<FUZZY_SLOP> { fuzzy=true; } ]
+      | fuzzySlop=<FUZZY_SLOP> { fuzzy=true; } [ <CARAT> boost=<NUMBER> ]
+    ]
+    { q = handleBareTokenQuery(getField(field), term, fuzzySlop, prefix, wildcard, fuzzy, regexp); }
+
+  | ( <RANGEIN_START> { startInc = true; } | <RANGEEX_START> )
+    ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> )
+    [ <RANGE_TO> ]
+    ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> )
+    ( <RANGEIN_END> { endInc = true; } | <RANGEEX_END> )
+    [ <CARAT> boost=<NUMBER> ]
     {
-      q = handleBareTokenQuery(getField(field), term, fuzzySlop, prefix, wildcard, fuzzy, regexp);
-    }
-    | ( ( <RANGEIN_START> {startInc=true;} | <RANGEEX_START> )
-        ( goop1=<RANGE_GOOP>|goop1=<RANGE_QUOTED> )
-        [ <RANGE_TO> ]
-        ( goop2=<RANGE_GOOP>|goop2=<RANGE_QUOTED> )
-        ( <RANGEIN_END> {endInc=true;} | <RANGEEX_END>))
-      [ <CARAT> boost=<NUMBER> ]
-       {
-         boolean startOpen=false;
-         boolean endOpen=false;
-         if (goop1.kind == RANGE_QUOTED) {
-           goop1.image = goop1.image.substring(1, goop1.image.length()-1);
-         } else if ("*".equals(goop1.image)) {
-           startOpen=true;
-         }
-         if (goop2.kind == RANGE_QUOTED) {
-           goop2.image = goop2.image.substring(1, goop2.image.length()-1);
-         } else if ("*".equals(goop2.image)) {
-           endOpen=true;
-         }
-         q = getRangeQuery(getField(field), startOpen ? null : discardEscapeChar(goop1.image), endOpen ? null : discardEscapeChar(goop2.image), startInc, endInc);
-       }
-    | term=<QUOTED>
-      [ fuzzySlop=<FUZZY_SLOP> ]
-      [ <CARAT> boost=<NUMBER> ]
-      {
-        q = handleQuotedTerm(getField(field), term, fuzzySlop);
+      boolean startOpen=false;
+      boolean endOpen=false;
+      if (goop1.kind == RANGE_QUOTED) {
+        goop1.image = goop1.image.substring(1, goop1.image.length()-1);
+      } else if ("*".equals(goop1.image)) {
+        startOpen=true;
+      }
+      if (goop2.kind == RANGE_QUOTED) {
+        goop2.image = goop2.image.substring(1, goop2.image.length()-1);
+      } else if ("*".equals(goop2.image)) {
+        endOpen=true;
       }
+      q = getRangeQuery(getField(field),
+                        startOpen ? null : discardEscapeChar(goop1.image),
+                        endOpen ? null : discardEscapeChar(goop2.image), startInc, endInc);
+    }
+  | term=<QUOTED>
+    [
+      <CARAT> boost=<NUMBER> [ fuzzySlop=<FUZZY_SLOP> { fuzzy=true; } ]
+      | fuzzySlop=<FUZZY_SLOP> { fuzzy=true; } [ <CARAT> boost=<NUMBER> ]
+    ]
+    { q = handleQuotedTerm(getField(field), term, fuzzySlop); }
   )
+  { return handleBoost(q, boost); }
+}
+
+void MultiTerm(String field, List<BooleanClause> clauses) throws SyntaxError : {
+  Token text;
+  List<String> terms = null;
+}
+{
+  text=<TERM>
+  {
+    if (splitOnWhitespace) {
+      Query q = getFieldQuery(getField(field), discardEscapeChar(text.image), false, true);
+      addClause(clauses, CONJ_NONE, MOD_NONE, q);
+    } else {
+      terms = new ArrayList<String>();
+      terms.add(discardEscapeChar(text.image));
+    }
+  }
+  // Both lookaheads are required; the first lookahead vets the first following term and the second lookahead vets the rest
+  LOOKAHEAD({ getToken(1).kind == TERM && allowedPostMultiTerm(getToken(2).kind) })
+  (
+    LOOKAHEAD({ getToken(1).kind == TERM && allowedPostMultiTerm(getToken(2).kind) })
+    text=<TERM>
+    {
+      if (splitOnWhitespace) {
+        Query q = getFieldQuery(getField(field), discardEscapeChar(text.image), false, true);
+        addClause(clauses, CONJ_NONE, MOD_NONE, q);
+      } else {
+        terms.add(discardEscapeChar(text.image));
+      }
+    }
+  )+
   {
-    return handleBoost(q, boost);
+    if (splitOnWhitespace == false) {
+      Query q = getFieldQuery(getField(field), terms, true);
+      addMultiTermClause(clauses, q);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
index 84ffcb9..08ccdd1 100644
--- a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
+++ b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
@@ -18,10 +18,12 @@ package org.apache.solr.parser;
 
 import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.reverse.ReverseStringFilter;
@@ -41,7 +43,6 @@ import org.apache.lucene.search.Query;
 import org.apache.lucene.search.RegexpQuery;
 import org.apache.lucene.search.WildcardQuery;
 import org.apache.lucene.util.QueryBuilder;
-import org.apache.lucene.util.Version;
 import org.apache.lucene.util.automaton.Automata;
 import org.apache.lucene.util.automaton.Automaton;
 import org.apache.lucene.util.automaton.Operations;
@@ -59,7 +60,7 @@ import org.apache.solr.search.SolrConstantScoreQuery;
 import org.apache.solr.search.SyntaxError;
 
 /** This class is overridden by QueryParser in QueryParser.jj
- * and acts to separate the majority of the Java code from the .jj grammar file. 
+ * and acts to separate the majority of the Java code from the .jj grammar file.
  */
 public abstract class SolrQueryParserBase extends QueryBuilder {
 
@@ -83,7 +84,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
   public static final Operator OR_OPERATOR = Operator.OR;
 
   /** The default operator that parser uses to combine query terms */
-  Operator operator = OR_OPERATOR;
+  protected Operator operator = OR_OPERATOR;
 
   MultiTermQuery.RewriteMethod multiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_REWRITE;
   boolean allowLeadingWildcard = true;
@@ -133,16 +134,32 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
   // internal: A simple raw fielded query
   public static class RawQuery extends Query {
     final SchemaField sfield;
-    final String externalVal;
+    private final List<String> externalVals;
 
     public RawQuery(SchemaField sfield, String externalVal) {
+      this(sfield, Collections.singletonList(externalVal));
+    }
+
+    public RawQuery(SchemaField sfield, List<String> externalVals) {
       this.sfield = sfield;
-      this.externalVal = externalVal;
+      this.externalVals = externalVals;
+    }
+
+    public int getTermCount() {
+      return externalVals.size();
+    }
+
+    public List<String> getExternalVals() {
+      return externalVals;
+    }
+
+    public String getJoinedExternalVal() {
+      return externalVals.size() == 1 ? externalVals.get(0) : String.join(" ", externalVals);
     }
 
     @Override
     public String toString(String field) {
-      return "RAW(" + field + "," + externalVal + ")";
+      return "RAW(" + field + "," + getJoinedExternalVal() + ")";
     }
 
     @Override
@@ -165,7 +182,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
   public abstract Query TopLevelQuery(String field) throws ParseException, SyntaxError;
 
 
-  public void init(Version matchVersion, String defaultField, QParser parser) {
+  public void init(String defaultField, QParser parser) {
     this.schema = parser.getReq().getSchema();
     this.parser = parser;
     this.flags = parser.getFlags();
@@ -406,17 +423,30 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
       throw new RuntimeException("Clause cannot be both required and prohibited");
   }
 
+  /**
+   * Called from QueryParser's MultiTerm rule.
+   * Assumption: no conjunction or modifiers (conj == CONJ_NONE and mods == MOD_NONE)
+   */
+  protected void addMultiTermClause(List<BooleanClause> clauses, Query q) {
+    // We might have been passed a null query; the term might have been
+    // filtered away by the analyzer.
+    if (q == null) {
+      return;
+    }
+    clauses.add(newBooleanClause(q, operator == AND_OPERATOR ? BooleanClause.Occur.MUST : BooleanClause.Occur.SHOULD));
+  }
 
-
-  protected Query newFieldQuery(Analyzer analyzer, String field, String queryText, boolean quoted)  throws SyntaxError {
+  protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
+                                boolean quoted, boolean fieldAutoGenPhraseQueries)  throws SyntaxError {
     BooleanClause.Occur occur = operator == Operator.AND ? BooleanClause.Occur.MUST : BooleanClause.Occur.SHOULD;
-    return createFieldQuery(analyzer, occur, field, queryText, quoted || autoGeneratePhraseQueries, phraseSlop);
+    return createFieldQuery(analyzer, occur, field, queryText,
+        quoted || fieldAutoGenPhraseQueries || autoGeneratePhraseQueries, phraseSlop);
   }
 
 
 
   /**
-   * Base implementation delegates to {@link #getFieldQuery(String,String,boolean)}.
+   * Base implementation delegates to {@link #getFieldQuery(String,String,boolean,boolean)}.
    * This method may be overridden, for example, to return
    * a SpanNearQuery instead of a PhraseQuery.
    *
@@ -440,7 +470,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
         query = builder.build();
       } else if (query instanceof MultiPhraseQuery) {
         MultiPhraseQuery mpq = (MultiPhraseQuery)query;
-      
+
         if (slop != mpq.getSlop()) {
           query = new MultiPhraseQuery.Builder(mpq).setSlop(slop).build();
         }
@@ -492,7 +522,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
   protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) {
     // FuzzyQuery doesn't yet allow constant score rewrite
     String text = term.text();
-    int numEdits = FuzzyQuery.floatToEdits(minimumSimilarity, 
+    int numEdits = FuzzyQuery.floatToEdits(minimumSimilarity,
         text.codePointCount(0, text.length()));
     return new FuzzyQuery(term,numEdits,prefixLength);
   }
@@ -536,14 +566,21 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
     }
 
     SchemaField sfield = null;
-    List<String> fieldValues = null;
-
+    List<RawQuery> fieldValues = null;
 
-    boolean useTermsQuery = (flags & QParser.FLAG_FILTER)!=0 && clauses.size() > TERMS_QUERY_THRESHOLD;
-    int clausesAdded = 0;
+    boolean onlyRawQueries = true;
+    int allRawQueriesTermCount = 0;
+    for (BooleanClause clause : clauses) {
+      if (clause.getQuery() instanceof RawQuery) {
+        allRawQueriesTermCount += ((RawQuery)clause.getQuery()).getTermCount();
+      } else {
+        onlyRawQueries = false;
+      }
+    }
+    boolean useTermsQuery = (flags & QParser.FLAG_FILTER)!=0 && allRawQueriesTermCount > TERMS_QUERY_THRESHOLD;
 
     BooleanQuery.Builder booleanBuilder = newBooleanQuery();
-    Map<SchemaField, List<String>> fmap = new HashMap<>();
+    Map<SchemaField, List<RawQuery>> fmap = new HashMap<>();
 
     for (BooleanClause clause : clauses) {
       Query subq = clause.getQuery();
@@ -563,14 +600,14 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
             // If this field isn't indexed, or if it is indexed and we want to use TermsQuery, then collect this value.
             // We are currently relying on things like PointField not being marked as indexed in order to bypass
             // the "useTermQuery" check.
-            if (fieldValues == null && useTermsQuery || !sfield.indexed()) {
+            if ((fieldValues == null && useTermsQuery) || !sfield.indexed()) {
               fieldValues = new ArrayList<>(2);
               fmap.put(sfield, fieldValues);
             }
           }
 
           if (fieldValues != null) {
-            fieldValues.add(rawq.externalVal);
+            fieldValues.add(rawq);
             continue;
           }
 
@@ -578,33 +615,50 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
         }
       }
 
-      clausesAdded++;
       booleanBuilder.add(clause);
     }
 
 
-    for (Map.Entry<SchemaField,List<String>> entry : fmap.entrySet()) {
+    for (Map.Entry<SchemaField,List<RawQuery>> entry : fmap.entrySet()) {
       sfield = entry.getKey();
       fieldValues = entry.getValue();
       FieldType ft = sfield.getType();
 
       // TODO: pull more of this logic out to FieldType?  We would need to be able to add clauses to our existing booleanBuilder.
-      if (sfield.indexed() && fieldValues.size() < TERMS_QUERY_THRESHOLD || fieldValues.size() == 1) {
+      int termCount = fieldValues.stream().mapToInt(RawQuery::getTermCount).sum();
+      if ((sfield.indexed() && termCount < TERMS_QUERY_THRESHOLD) || termCount == 1) {
         // use boolean query instead
-        for (String externalVal : fieldValues) {
-          Query subq = ft.getFieldQuery(this.parser, sfield, externalVal);
-          clausesAdded++;
-          booleanBuilder.add(subq, BooleanClause.Occur.SHOULD);
+        for (RawQuery rawq : fieldValues) {
+          Query subq;
+          if (ft.isTokenized() && sfield.indexed()) {
+            boolean fieldAutoGenPhraseQueries = ft instanceof TextField && ((TextField)ft).getAutoGeneratePhraseQueries();
+            subq = newFieldQuery(getAnalyzer(), sfield.getName(), rawq.getJoinedExternalVal(),
+                false, fieldAutoGenPhraseQueries);
+            booleanBuilder.add(subq, BooleanClause.Occur.SHOULD);
+          } else {
+            for (String externalVal : rawq.getExternalVals()) {
+              subq = ft.getFieldQuery(this.parser, sfield, externalVal);
+              booleanBuilder.add(subq, BooleanClause.Occur.SHOULD);
+            }
+          }
         }
       } else {
-        Query subq = ft.getSetQuery(this.parser, sfield, fieldValues);
-        if (fieldValues.size() == clauses.size()) return subq; // if this is everything, don't wrap in a boolean query
-        clausesAdded++;
+        List<String> externalVals
+            = fieldValues.stream().flatMap(rawq -> rawq.getExternalVals().stream()).collect(Collectors.toList());
+        Query subq = ft.getSetQuery(this.parser, sfield, externalVals);
+        if (onlyRawQueries && termCount == allRawQueriesTermCount) return subq; // if this is everything, don't wrap in a boolean query
         booleanBuilder.add(subq, BooleanClause.Occur.SHOULD);
       }
     }
 
-    return booleanBuilder.build();
+    BooleanQuery bq = booleanBuilder.build();
+    if (bq.clauses().size() == 1) { // Unwrap single SHOULD query
+      BooleanClause clause = bq.clauses().iterator().next();
+      if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
+        return clause.getQuery();
+      }
+    }
+    return bq;
   }
 
 
@@ -623,7 +677,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
     } else if (fuzzy) {
       float fms = fuzzyMinSim;
       try {
-        fms = Float.valueOf(fuzzySlop.image.substring(1)).floatValue();
+        fms = Float.parseFloat(fuzzySlop.image.substring(1));
       } catch (Exception ignored) { }
       if(fms < 0.0f){
         throw new SyntaxError("Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !");
@@ -644,7 +698,7 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
     int s = phraseSlop;  // default
     if (fuzzySlop != null) {
       try {
-        s = Float.valueOf(fuzzySlop.image.substring(1)).intValue();
+        s = (int)Float.parseFloat(fuzzySlop.image.substring(1));
       }
       catch (Exception ignored) { }
     }
@@ -835,9 +889,26 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
 
   // Create a "normal" query from a RawQuery (or just return the current query if it's not raw)
   Query rawToNormal(Query q) {
-    if (!(q instanceof RawQuery)) return q;
-    RawQuery rq = (RawQuery)q;
-    return rq.sfield.getType().getFieldQuery(parser, rq.sfield, rq.externalVal);
+    Query normal = q;
+    if (q instanceof RawQuery) {
+      RawQuery rawq = (RawQuery)q;
+      if (rawq.sfield.getType().isTokenized()) {
+        normal = rawq.sfield.getType().getFieldQuery(parser, rawq.sfield, rawq.getJoinedExternalVal());
+      } else {
+        FieldType ft = rawq.sfield.getType();
+        if (rawq.getTermCount() == 1) {
+          normal = ft.getFieldQuery(this.parser, rawq.sfield, rawq.getExternalVals().get(0));
+        } else {
+          BooleanQuery.Builder booleanBuilder = newBooleanQuery();
+          for (String externalVal : rawq.getExternalVals()) {
+            Query subq = ft.getFieldQuery(this.parser, rawq.sfield, externalVal);
+            booleanBuilder.add(subq, BooleanClause.Occur.SHOULD);
+          }
+          normal = booleanBuilder.build();
+        }
+      }
+    }
+    return normal;
   }
 
   protected Query getFieldQuery(String field, String queryText, boolean quoted) throws SyntaxError {
@@ -877,21 +948,87 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
       FieldType ft = sf.getType();
       // delegate to type for everything except tokenized fields
       if (ft.isTokenized() && sf.indexed()) {
-        return newFieldQuery(getAnalyzer(), field, queryText, quoted || (ft instanceof TextField && ((TextField)ft).getAutoGeneratePhraseQueries()));
+        boolean fieldAutoGenPhraseQueries = ft instanceof TextField && ((TextField)ft).getAutoGeneratePhraseQueries();
+        return newFieldQuery(getAnalyzer(), field, queryText, quoted, fieldAutoGenPhraseQueries);
       } else {
         if (raw) {
           return new RawQuery(sf, queryText);
         } else {
-          return sf.getType().getFieldQuery(parser, sf, queryText);
+          return ft.getFieldQuery(parser, sf, queryText);
+        }
+      }
+    }
+
+    // default to a normal field query
+    return newFieldQuery(getAnalyzer(), field, queryText, quoted, false);
+  }
+
+  // Assumption: quoted is always false
+  protected Query getFieldQuery(String field, List<String> queryTerms, boolean raw) throws SyntaxError {
+    checkNullField(field);
+
+    SchemaField sf;
+    if (field.equals(lastFieldName)) {
+      // only look up the SchemaField on a field change... this helps with memory allocation of dynamic fields
+      // and large queries like foo_i:(1 2 3 4 5 6 7 8 9 10) when we are passed "foo_i" each time.
+      sf = lastField;
+    } else {
+      // intercept magic field name of "_" to use as a hook for our
+      // own functions.
+      if (field.charAt(0) == '_' && parser != null) {
+        MagicFieldName magic = MagicFieldName.get(field);
+        if (null != magic) {
+          subQParser = parser.subQuery(String.join(" ", queryTerms), magic.subParser);
+          return subQParser.getQuery();
+        }
+      }
+
+      lastFieldName = field;
+      sf = lastField = schema.getFieldOrNull(field);
+    }
+
+    if (sf != null) {
+      FieldType ft = sf.getType();
+      // delegate to type for everything except tokenized fields
+      if (ft.isTokenized() && sf.indexed()) {
+        String queryText = queryTerms.size() == 1 ? queryTerms.get(0) : String.join(" ", queryTerms);
+        boolean fieldAutoGenPhraseQueries = ft instanceof TextField && ((TextField)ft).getAutoGeneratePhraseQueries();
+        return newFieldQuery(getAnalyzer(), field, queryText, false, fieldAutoGenPhraseQueries);
+      } else {
+        if (raw) {
+          return new RawQuery(sf, queryTerms);
+        } else {
+          if (queryTerms.size() == 1) {
+            return ft.getFieldQuery(parser, sf, queryTerms.get(0));
+          } else {
+            List<Query> subqs = new ArrayList<>();
+            for (String queryTerm : queryTerms) {
+              try {
+                subqs.add(ft.getFieldQuery(parser, sf, queryTerm));
+              } catch (Exception e) { // assumption: raw = false only when called from ExtendedDismaxQueryParser.getQuery()
+                // for edismax: ignore parsing failures
+              }
+            }
+            if (subqs.size() == 1) {
+              return subqs.get(0);
+            } else { // delay building boolean query until we must
+              final BooleanClause.Occur occur
+                  = operator == AND_OPERATOR ? BooleanClause.Occur.MUST : BooleanClause.Occur.SHOULD;
+              BooleanQuery.Builder booleanBuilder = newBooleanQuery();
+              subqs.forEach(subq -> booleanBuilder.add(subq, occur));
+              return booleanBuilder.build();
+            }
+          }
         }
       }
     }
 
     // default to a normal field query
-    return newFieldQuery(getAnalyzer(), field, queryText, quoted);
+    String queryText = queryTerms.size() == 1 ? queryTerms.get(0) : String.join(" ", queryTerms);
+    return newFieldQuery(getAnalyzer(), field, queryText, false, false);
   }
 
- protected boolean isRangeShouldBeProtectedFromReverse(String field, String part1){
+  protected boolean isRangeShouldBeProtectedFromReverse(String field, String part1){
    checkNullField(field);
    SchemaField sf = schema.getField(field);
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/response/transform/BaseEditorialTransformer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/response/transform/BaseEditorialTransformer.java b/solr/core/src/java/org/apache/solr/response/transform/BaseEditorialTransformer.java
index 80e0b61..bc5fb65 100644
--- a/solr/core/src/java/org/apache/solr/response/transform/BaseEditorialTransformer.java
+++ b/solr/core/src/java/org/apache/solr/response/transform/BaseEditorialTransformer.java
@@ -17,12 +17,12 @@
 package org.apache.solr.response.transform;
 
 
-import org.apache.lucene.document.Field;
+import java.util.Set;
+
+import org.apache.lucene.index.IndexableField;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.schema.FieldType;
 
-import java.util.Set;
-
 /**
  *
  *
@@ -40,8 +40,7 @@ public abstract class BaseEditorialTransformer extends DocTransformer {
   }
 
   @Override
-  public String getName()
-  {
+  public String getName() {
     return name;
   }
 
@@ -61,22 +60,15 @@ public abstract class BaseEditorialTransformer extends DocTransformer {
   protected abstract Set<String> getIdSet();
 
   protected String getKey(SolrDocument doc) {
-    String key;
-    Object field = doc.get(idFieldName);
-    final Number n;
-    if (field instanceof Field) {
-      n = ((Field) field).numericValue();
-    } else {
-      n = null;
-    }
-    if (n != null) {
-      key = n.toString();
-      key = ft.readableToIndexed(key);
-    } else if (field instanceof Field){
-      key = ((Field)field).stringValue();
-    } else {
-      key = field.toString();
+    Object obj = doc.get(idFieldName);
+    if (obj instanceof IndexableField) {
+      IndexableField f = (IndexableField) obj;
+      Number n = f.numericValue();
+      if (n != null) {
+        return ft.readableToIndexed(n.toString());
+      }
+      return ft.readableToIndexed(f.stringValue());
     }
-    return key;
+    throw new AssertionError("Expected an IndexableField but got: " + obj.getClass());
   }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java b/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java
index a674040..d25ab89 100644
--- a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java
+++ b/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java
@@ -25,7 +25,9 @@ import javax.xml.parsers.ParserConfigurationException;
 
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.SimilarityFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -83,9 +85,30 @@ public class FieldTypeXmlAdapter {
           jsonFieldName+" not a "+jsonField.getClass().getName());
 
     Element similarity = doc.createElement("similarity");
-    appendAttrs(similarity, (Map<String,?>)jsonField);
+    Map<String,?> config = (Map<String,?>)jsonField;
+    similarity.setAttribute(SimilarityFactory.CLASS_NAME, (String)config.remove(SimilarityFactory.CLASS_NAME));
+    for (Map.Entry<String,?> entry : config.entrySet()) {
+      Object val = entry.getValue();
+      if (val != null) {
+        Element child = doc.createElement(classToXmlTag(val.getClass()));
+        child.setAttribute(CommonParams.NAME, entry.getKey());
+        child.setTextContent(entry.getValue().toString());
+        similarity.appendChild(child);
+      }
+    }
     return similarity;
   }
+
+  /** Convert types produced by noggit's ObjectBuilder (Boolean, Double, Long, String) to plugin param XML tags. */
+  protected static String classToXmlTag(Class<?> clazz) {
+    switch (clazz.getSimpleName()) {
+      case "Boolean": return "bool";
+      case "Double":  return "double";
+      case "Long":    return "long";
+      case "String":  return "str";
+    }
+    throw new SolrException(ErrorCode.BAD_REQUEST, "Unsupported object type '" + clazz.getSimpleName() + "'");
+  }
   
   @SuppressWarnings("unchecked")
   protected static Element transformAnalyzer(Document doc, Map<String,?> json, String jsonFieldName, String analyzerType) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java b/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java
index 4e2829e..2106205 100644
--- a/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java
@@ -225,7 +225,7 @@ public abstract class AbstractSpatialFieldType<T extends SpatialStrategy> extend
     }
 
     List<IndexableField> result = new ArrayList<>();
-    if (field.indexed()) {
+    if (field.indexed() || field.hasDocValues()) {
       T strategy = getStrategy(field.getName());
       result.addAll(Arrays.asList(strategy.createIndexableFields(shape)));
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/AbstractSubTypeFieldType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/AbstractSubTypeFieldType.java b/solr/core/src/java/org/apache/solr/schema/AbstractSubTypeFieldType.java
index 1184876..73a4f3c 100644
--- a/solr/core/src/java/org/apache/solr/schema/AbstractSubTypeFieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/AbstractSubTypeFieldType.java
@@ -76,20 +76,25 @@ public abstract class AbstractSubTypeFieldType extends FieldType implements Sche
    * and props of indexed=true, stored=false.
    *
    * @param schema the IndexSchema
-   * @param type   The {@link FieldType} of the prototype.
+   * @param subType   The {@link FieldType} of the prototype.
+   * @param polyField   The poly {@link FieldType}.
    * @return The {@link SchemaField}
    */
 
-  static SchemaField registerPolyFieldDynamicPrototype(IndexSchema schema, FieldType type) {
-    String name = "*" + FieldType.POLY_FIELD_SEPARATOR + type.typeName;
+  static SchemaField registerPolyFieldDynamicPrototype(IndexSchema schema, FieldType subType, FieldType polyField) {
+    String name = "*" + FieldType.POLY_FIELD_SEPARATOR + subType.typeName;
     Map<String, String> props = new HashMap<>();
     //Just set these, delegate everything else to the field type
     props.put("indexed", "true");
     props.put("stored", "false");
     props.put("multiValued", "false");
-    int p = SchemaField.calcProps(name, type, props);
+    // if polyField enables dv, add them to the subtypes
+    if (polyField.hasProperty(DOC_VALUES)) {
+      props.put("docValues", "true");
+    }
+    int p = SchemaField.calcProps(name, subType, props);
     SchemaField proto = SchemaField.create(name,
-            type, p, null);
+        subType, p, null);
     schema.registerDynamicFields(proto);
     return proto;
   }
@@ -107,7 +112,7 @@ public abstract class AbstractSubTypeFieldType extends FieldType implements Sche
     this.schema = schema;
     //Can't do this until here b/c the Dynamic Fields are not initialized until here.
     if (subType != null) {
-      SchemaField proto = registerPolyFieldDynamicPrototype(schema, subType);
+      SchemaField proto = registerPolyFieldDynamicPrototype(schema, subType, this);
       dynFieldProps = proto.getProperties();
     }
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/BinaryField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/BinaryField.java b/solr/core/src/java/org/apache/solr/schema/BinaryField.java
index d1882b1..a0e7d05 100644
--- a/solr/core/src/java/org/apache/solr/schema/BinaryField.java
+++ b/solr/core/src/java/org/apache/solr/schema/BinaryField.java
@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
 import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.util.BytesRef;
+import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.Base64;
 import org.apache.solr.response.TextResponseWriter;
 import org.apache.solr.uninverting.UninvertingReader.Type;
@@ -34,6 +35,14 @@ public class BinaryField extends FieldType  {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  @Override
+  public void checkSchemaField(SchemaField field) {
+    super.checkSchemaField(field);
+    if (field.isLarge()) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Field type " + this + " is 'large'; not supported (yet)");
+    }
+  }
+
   private String toBase64String(ByteBuffer buf) {
     return Base64.byteArrayToBase64(buf.array(), buf.position(), buf.limit()-buf.position());
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/BoolField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/BoolField.java b/solr/core/src/java/org/apache/solr/schema/BoolField.java
index 7d5c0d7..607e384 100644
--- a/solr/core/src/java/org/apache/solr/schema/BoolField.java
+++ b/solr/core/src/java/org/apache/solr/schema/BoolField.java
@@ -207,9 +207,6 @@ public class BoolField extends PrimitiveFieldType {
     return Collections.singletonList(fval);
   }
 
-  @Override
-  public void checkSchemaField(final SchemaField field) {
-  }
 }
 
 // TODO - this can be much more efficient - use FixedBitSet or Bits

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/CollationField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/CollationField.java b/solr/core/src/java/org/apache/solr/schema/CollationField.java
index a498c01..c6a4f81 100644
--- a/solr/core/src/java/org/apache/solr/schema/CollationField.java
+++ b/solr/core/src/java/org/apache/solr/schema/CollationField.java
@@ -247,10 +247,9 @@ public class CollationField extends FieldType {
       return new TermRangeQuery(field.getName(), low, high, minInclusive, maxInclusive);
     }
   }
-  
+
   @Override
-  public void checkSchemaField(SchemaField field) {
-    // no-op
+  protected void checkSupportsDocValues() { // we support DocValues
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/DatePointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/DatePointField.java b/solr/core/src/java/org/apache/solr/schema/DatePointField.java
index b3517db..377f571 100644
--- a/solr/core/src/java/org/apache/solr/schema/DatePointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/DatePointField.java
@@ -17,7 +17,6 @@
 
 package org.apache.solr.schema;
 
-import java.lang.invoke.MethodHandles;
 import java.time.Instant;
 import java.util.Collection;
 import java.util.Date;
@@ -25,7 +24,6 @@ import java.util.Date;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.legacy.LegacyNumericType;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.LongFieldSource;
 import org.apache.lucene.queries.function.valuesource.MultiValuedLongFieldSource;
@@ -39,13 +37,9 @@ import org.apache.lucene.util.mutable.MutableValueLong;
 import org.apache.solr.search.QParser;
 import org.apache.solr.uninverting.UninvertingReader;
 import org.apache.solr.util.DateMathParser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class DatePointField extends PointField implements DateValueFieldType {
 
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
   public DatePointField() {
     type = NumberType.DATE;
   }
@@ -165,11 +159,6 @@ public class DatePointField extends PointField implements DateValueFieldType {
   }
 
   @Override
-  public LegacyNumericType getNumericType() {
-    return LegacyNumericType.LONG;
-  }
-
-  @Override
   public IndexableField createField(SchemaField field, Object value) {
     if (!isFieldUsed(field)) return null;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
index e34ebec..6ae8349 100644
--- a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
@@ -17,14 +17,12 @@
 
 package org.apache.solr.schema;
 
-import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 
 import org.apache.lucene.document.DoublePoint;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.index.DocValuesType;
 import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.legacy.LegacyNumericType;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
 import org.apache.lucene.queries.function.valuesource.MultiValuedDoubleFieldSource;
@@ -36,8 +34,6 @@ import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.solr.search.QParser;
 import org.apache.solr.uninverting.UninvertingReader.Type;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * {@code PointField} implementation for {@code Double} values.
@@ -46,8 +42,6 @@ import org.slf4j.LoggerFactory;
  */
 public class DoublePointField extends PointField implements DoubleValueFieldType {
 
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
   public DoublePointField() {
     type = NumberType.DOUBLE;
   }
@@ -172,12 +166,6 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
   }
 
   @Override
-  public LegacyNumericType getNumericType() {
-    // TODO: refactor this to not use LegacyNumericType
-    return LegacyNumericType.DOUBLE;
-  }
-
-  @Override
   public IndexableField createField(SchemaField field, Object value) {
     if (!isFieldUsed(field)) return null;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/EnumField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/EnumField.java b/solr/core/src/java/org/apache/solr/schema/EnumField.java
index 3e83db4..3127262 100644
--- a/solr/core/src/java/org/apache/solr/schema/EnumField.java
+++ b/solr/core/src/java/org/apache/solr/schema/EnumField.java
@@ -233,15 +233,6 @@ public class EnumField extends PrimitiveFieldType {
    * {@inheritDoc}
    */
   @Override
-  @Deprecated
-  public LegacyNumericType getNumericType() {
-    return LegacyNumericType.INT;
-  }
-  
-  /**
-   * {@inheritDoc}
-   */
-  @Override
   public NumberType getNumberType() {
     return NumberType.INTEGER;
   }
@@ -290,13 +281,6 @@ public class EnumField extends PrimitiveFieldType {
    * {@inheritDoc}
    */
   @Override
-  public void checkSchemaField(SchemaField field) {
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
   public String readableToIndexed(String val) {
     if (val == null)
       return null;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/FieldProperties.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/FieldProperties.java b/solr/core/src/java/org/apache/solr/schema/FieldProperties.java
index 2b1a8bb..6762345 100644
--- a/solr/core/src/java/org/apache/solr/schema/FieldProperties.java
+++ b/solr/core/src/java/org/apache/solr/schema/FieldProperties.java
@@ -30,29 +30,30 @@ public abstract class FieldProperties {
   // many of the variables are independent or semi-independent.
 
   // bit values for boolean field properties.
-  protected final static int INDEXED             = 0x00000001;
-  protected final static int TOKENIZED           = 0x00000002;
-  protected final static int STORED              = 0x00000004;
-  protected final static int BINARY              = 0x00000008;
-  protected final static int OMIT_NORMS          = 0x00000010;
-  protected final static int OMIT_TF_POSITIONS   = 0x00000020;
-  protected final static int STORE_TERMVECTORS   = 0x00000040;
-  protected final static int STORE_TERMPOSITIONS = 0x00000080;
-  protected final static int STORE_TERMOFFSETS   = 0x00000100;
-
-
-  protected final static int MULTIVALUED         = 0x00000200;
-  protected final static int SORT_MISSING_FIRST  = 0x00000400;
-  protected final static int SORT_MISSING_LAST   = 0x00000800;
+  protected final static int INDEXED             = 0b1;
+  protected final static int TOKENIZED           = 0b10;
+  protected final static int STORED              = 0b100;
+  protected final static int BINARY              = 0b1000;
+  protected final static int OMIT_NORMS          = 0b10000;
+  protected final static int OMIT_TF_POSITIONS   = 0b100000;
+  protected final static int STORE_TERMVECTORS   = 0b1000000;
+  protected final static int STORE_TERMPOSITIONS = 0b10000000;
+  protected final static int STORE_TERMOFFSETS   = 0b100000000;
+
+
+  protected final static int MULTIVALUED         = 0b1000000000;
+  protected final static int SORT_MISSING_FIRST  = 0b10000000000;
+  protected final static int SORT_MISSING_LAST   = 0b100000000000;
   
-  protected final static int REQUIRED            = 0x00001000;
-  protected final static int OMIT_POSITIONS      = 0x00002000;
+  protected final static int REQUIRED            = 0b1000000000000;
+  protected final static int OMIT_POSITIONS      = 0b10000000000000;
 
-  protected final static int STORE_OFFSETS       = 0x00004000;
-  protected final static int DOC_VALUES          = 0x00008000;
+  protected final static int STORE_OFFSETS       = 0b100000000000000;
+  protected final static int DOC_VALUES          = 0b1000000000000000;
 
-  protected final static int STORE_TERMPAYLOADS  = 0x00010000;
-  protected final static int USE_DOCVALUES_AS_STORED  = 0x00020000;
+  protected final static int STORE_TERMPAYLOADS  = 0b10000000000000000;
+  protected final static int USE_DOCVALUES_AS_STORED  = 0b100000000000000000;
+  protected final static int LARGE_FIELD         = 0b1000000000000000000;
 
   static final String[] propertyNames = {
           "indexed", "tokenized", "stored",
@@ -60,7 +61,7 @@ public abstract class FieldProperties {
           "termVectors", "termPositions", "termOffsets",
           "multiValued",
           "sortMissingFirst","sortMissingLast","required", "omitPositions",
-          "storeOffsetsWithPositions", "docValues", "termPayloads", "useDocValuesAsStored"
+          "storeOffsetsWithPositions", "docValues", "termPayloads", "useDocValuesAsStored", "large"
   };
 
   static final Map<String,Integer> propertyMap = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/FieldType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/FieldType.java b/solr/core/src/java/org/apache/solr/schema/FieldType.java
index c542a95..016e166 100644
--- a/solr/core/src/java/org/apache/solr/schema/FieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/FieldType.java
@@ -39,7 +39,6 @@ import org.apache.lucene.document.Field;
 import org.apache.lucene.document.SortedSetDocValuesField;
 import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.Term;
-import org.apache.lucene.legacy.LegacyNumericType;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
@@ -610,16 +609,6 @@ public abstract class FieldType extends FieldProperties {
     return similarityFactory;
   }
 
-
-  /** Return the numeric type of this field, or null if this field is not a
-   *  numeric field. 
-   *  @deprecated Please use {@link FieldType#getNumberType()} instead
-   */
-  @Deprecated
-  public LegacyNumericType getNumericType() {
-    return null;
-  }
-  
   /**
    * Return the numeric type of this field, or null if this field is not a
    * numeric field. 
@@ -802,17 +791,27 @@ public abstract class FieldType extends FieldProperties {
    *
    * <p>
    * This method is called by the <code>SchemaField</code> constructor to 
-   * check that its initialization does not violate any fundemental 
-   * requirements of the <code>FieldType</code>.  The default implementation 
-   * does nothing, but subclasses may chose to throw a {@link SolrException}  
+   * check that its initialization does not violate any fundamental
+   * requirements of the <code>FieldType</code>.
+   * Subclasses may choose to throw a {@link SolrException}
    * if invariants are violated by the <code>SchemaField.</code>
    * </p>
    */
   public void checkSchemaField(final SchemaField field) {
-    // override if your field type supports doc values
     if (field.hasDocValues()) {
-      throw new SolrException(ErrorCode.SERVER_ERROR, "Field type " + this + " does not support doc values");
+      checkSupportsDocValues();
     }
+    if (field.isLarge() && field.multiValued()) {
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Field type " + this + " is 'large'; can't support multiValued");
+    }
+    if (field.isLarge() && getNumberType() != null) {
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Field type " + this + " is 'large'; can't support numerics");
+    }
+  }
+
+  /** Called by {@link #checkSchemaField(SchemaField)} if the field has docValues. By default none do. */
+  protected void checkSupportsDocValues() {
+    throw new SolrException(ErrorCode.SERVER_ERROR, "Field type " + this + " does not support doc values");
   }
 
   public static final String TYPE = "type";

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
index 39453e7..0f42cfd 100644
--- a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
@@ -17,14 +17,12 @@
 
 package org.apache.solr.schema;
 
-import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 
 import org.apache.lucene.document.FloatPoint;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.index.DocValuesType;
 import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.legacy.LegacyNumericType;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
 import org.apache.lucene.queries.function.valuesource.MultiValuedFloatFieldSource;
@@ -36,8 +34,6 @@ import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.solr.search.QParser;
 import org.apache.solr.uninverting.UninvertingReader.Type;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * {@code PointField} implementation for {@code Float} values.
@@ -46,8 +42,6 @@ import org.slf4j.LoggerFactory;
  */
 public class FloatPointField extends PointField implements FloatValueFieldType {
 
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
   public FloatPointField() {
     type = NumberType.FLOAT;
   }
@@ -171,13 +165,6 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
     return new MultiValuedFloatFieldSource(f.getName(), choice);
   }
 
-
-  @Override
-  public LegacyNumericType getNumericType() {
-    // TODO: refactor this to not use LegacyNumericType
-    return LegacyNumericType.FLOAT;
-  }
-
   @Override
   public IndexableField createField(SchemaField field, Object value) {
     if (!isFieldUsed(field)) return null;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/java/org/apache/solr/schema/IntPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/IntPointField.java b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
index db26988..5eaf7e0 100644
--- a/solr/core/src/java/org/apache/solr/schema/IntPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
@@ -17,13 +17,11 @@
 
 package org.apache.solr.schema;
 
-import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 
 import org.apache.lucene.document.IntPoint;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.legacy.LegacyNumericType;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.IntFieldSource;
 import org.apache.lucene.queries.function.valuesource.MultiValuedIntFieldSource;
@@ -34,8 +32,6 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.solr.search.QParser;
 import org.apache.solr.uninverting.UninvertingReader.Type;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * {@code PointField} implementation for {@code Integer} values.
@@ -44,8 +40,6 @@ import org.slf4j.LoggerFactory;
  */
 public class IntPointField extends PointField implements IntValueFieldType {
 
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
   public IntPointField() {
     type = NumberType.INTEGER;
   }
@@ -164,11 +158,6 @@ public class IntPointField extends PointField implements IntValueFieldType {
   }
 
   @Override
-  public LegacyNumericType getNumericType() {
-    return LegacyNumericType.INT;
-  }
-
-  @Override
   public IndexableField createField(SchemaField field, Object value) {
     if (!isFieldUsed(field)) return null;