You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2015/04/03 23:27:05 UTC

svn commit: r1671163 [1/3] - in /lucene/dev/trunk: ./ dev-tools/ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/backward-codecs/ lucene/benchmark/ lucene/classification/ lucene/codecs/ lucene/codecs/src/java/org/apache/lucene/codecs/blockterms...

Author: rmuir
Date: Fri Apr  3 21:27:03 2015
New Revision: 1671163

URL: http://svn.apache.org/r1671163
Log:
LUCENE-6271: PostingsEnum should have consistent flags behavior

Removed:
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestPostingsEnum.java
Modified:
    lucene/dev/trunk/   (props changed)
    lucene/dev/trunk/dev-tools/   (props changed)
    lucene/dev/trunk/lucene/   (props changed)
    lucene/dev/trunk/lucene/BUILD.txt   (props changed)
    lucene/dev/trunk/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/trunk/lucene/JRE_VERSION_MIGRATION.txt   (props changed)
    lucene/dev/trunk/lucene/LICENSE.txt   (props changed)
    lucene/dev/trunk/lucene/MIGRATE.txt   (props changed)
    lucene/dev/trunk/lucene/NOTICE.txt   (props changed)
    lucene/dev/trunk/lucene/README.txt   (props changed)
    lucene/dev/trunk/lucene/SYSTEM_REQUIREMENTS.txt   (props changed)
    lucene/dev/trunk/lucene/analysis/   (props changed)
    lucene/dev/trunk/lucene/analysis/common/   (props changed)
    lucene/dev/trunk/lucene/backward-codecs/   (props changed)
    lucene/dev/trunk/lucene/benchmark/   (props changed)
    lucene/dev/trunk/lucene/build.xml   (props changed)
    lucene/dev/trunk/lucene/classification/   (props changed)
    lucene/dev/trunk/lucene/codecs/   (props changed)
    lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java
    lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java
    lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java
    lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java
    lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java
    lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java
    lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
    lucene/dev/trunk/lucene/common-build.xml   (props changed)
    lucene/dev/trunk/lucene/core/   (props changed)
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/LeafReader.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiFields.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitPositions.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestStressIndexing2.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsReader.java
    lucene/dev/trunk/lucene/demo/   (props changed)
    lucene/dev/trunk/lucene/expressions/   (props changed)
    lucene/dev/trunk/lucene/facet/   (props changed)
    lucene/dev/trunk/lucene/grouping/   (props changed)
    lucene/dev/trunk/lucene/highlighter/   (props changed)
    lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java
    lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java
    lucene/dev/trunk/lucene/ivy-ignore-conflicts.properties   (props changed)
    lucene/dev/trunk/lucene/ivy-settings.xml   (props changed)
    lucene/dev/trunk/lucene/ivy-versions.properties   (props changed)
    lucene/dev/trunk/lucene/join/   (props changed)
    lucene/dev/trunk/lucene/licenses/   (props changed)
    lucene/dev/trunk/lucene/memory/   (props changed)
    lucene/dev/trunk/lucene/misc/   (props changed)
    lucene/dev/trunk/lucene/misc/src/java/org/apache/lucene/index/SortingLeafReader.java
    lucene/dev/trunk/lucene/module-build.xml   (props changed)
    lucene/dev/trunk/lucene/queries/   (props changed)
    lucene/dev/trunk/lucene/queryparser/   (props changed)
    lucene/dev/trunk/lucene/replicator/   (props changed)
    lucene/dev/trunk/lucene/sandbox/   (props changed)
    lucene/dev/trunk/lucene/site/   (props changed)
    lucene/dev/trunk/lucene/spatial/   (props changed)
    lucene/dev/trunk/lucene/suggest/   (props changed)
    lucene/dev/trunk/lucene/test-framework/   (props changed)
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/BasePostingsFormatTestCase.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/BaseTermVectorsFormatTestCase.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
    lucene/dev/trunk/lucene/tools/   (props changed)
    lucene/dev/trunk/lucene/version.properties   (props changed)
    lucene/dev/trunk/solr/   (props changed)
    lucene/dev/trunk/solr/CHANGES.txt   (props changed)
    lucene/dev/trunk/solr/LICENSE.txt   (props changed)
    lucene/dev/trunk/solr/NOTICE.txt   (props changed)
    lucene/dev/trunk/solr/README.txt   (props changed)
    lucene/dev/trunk/solr/bin/   (props changed)
    lucene/dev/trunk/solr/build.xml   (props changed)
    lucene/dev/trunk/solr/cloud-dev/   (props changed)
    lucene/dev/trunk/solr/common-build.xml   (props changed)
    lucene/dev/trunk/solr/contrib/   (props changed)
    lucene/dev/trunk/solr/contrib/velocity/src/test-files/velocity/solr/collection1/conf/velocity/numFound.vm   (props changed)
    lucene/dev/trunk/solr/core/   (props changed)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
    lucene/dev/trunk/solr/example/   (props changed)
    lucene/dev/trunk/solr/licenses/   (props changed)
    lucene/dev/trunk/solr/scripts/   (props changed)
    lucene/dev/trunk/solr/server/   (props changed)
    lucene/dev/trunk/solr/site/   (props changed)
    lucene/dev/trunk/solr/site/SYSTEM_REQUIREMENTS.mdtext   (props changed)
    lucene/dev/trunk/solr/solrj/   (props changed)
    lucene/dev/trunk/solr/test-framework/   (props changed)
    lucene/dev/trunk/solr/webapp/   (props changed)

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Fri Apr  3 21:27:03 2015
@@ -208,7 +208,7 @@ API Changes
 * LUCENE-6218, LUCENE-6220: Add Collector.needsScores() and needsScores
   parameter to Query.createWeight(). (Robert Muir, Adrien Grand)
 
-* LUCENE-4524, LUCENE-6246, LUCENE-6256: Merge DocsEnum and DocsAndPositionsEnum
+* LUCENE-4524, LUCENE-6246, LUCENE-6256, LUCENE-6271: Merge DocsEnum and DocsAndPositionsEnum
   into a single PostingsEnum iterator.  TermsEnum.docs() and TermsEnum.docsAndPositions()
   are replaced by TermsEnum.postings(). 
   (Alan Woodward, Simon Willnauer, Robert Muir, Ryan Ernst)

Modified: lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java (original)
+++ lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/BlockTermsReader.java Fri Apr  3 21:27:03 2015
@@ -652,14 +652,6 @@ public class BlockTermsReader extends Fi
 
       @Override
       public PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) throws IOException {
-
-        if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-          if (fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0) {
-            // Positions were not indexed:
-            return null;
-          }
-        }
-
         //System.out.println("BTR.docs this=" + this);
         decodeMetaData();
         //System.out.println("BTR.docs:  state.docFreq=" + state.docFreq);

Modified: lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java (original)
+++ lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsIntersectTermsEnum.java Fri Apr  3 21:27:03 2015
@@ -203,14 +203,6 @@ final class OrdsIntersectTermsEnum exten
 
   @Override
   public PostingsEnum postings(Bits skipDocs, PostingsEnum reuse, int flags) throws IOException {
-
-    if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-      if (fr.fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0) {
-        // Positions were not indexed:
-        return null;
-      }
-    }
-
     currentFrame.decodeMetaData();
     return fr.parent.postingsReader.postings(fr.fieldInfo, currentFrame.termState, skipDocs, reuse, flags);
   }

Modified: lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java (original)
+++ lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/blocktreeords/OrdsSegmentTermsEnum.java Fri Apr  3 21:27:03 2015
@@ -924,14 +924,6 @@ public final class OrdsSegmentTermsEnum
 
   @Override
   public PostingsEnum postings(Bits skipDocs, PostingsEnum reuse, int flags) throws IOException {
-
-    if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-      if (fr.fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0) {
-        // Positions were not indexed:
-        return null;
-      }
-    }
-
     assert !eof;
     //if (DEBUG) {
     //System.out.println("BTTR.docs seg=" + segment);

Modified: lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java (original)
+++ lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java Fri Apr  3 21:27:03 2015
@@ -860,19 +860,47 @@ public final class DirectPostingsFormat
         // TODO: implement reuse
         // it's hairy!
 
+        // TODO: the logic of which enum impl to choose should be refactored to be simpler...
         if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-          if (!hasPos) {
-            return null;
-          }
 
           if (terms[termOrd] instanceof LowFreqTerm) {
             final LowFreqTerm term = ((LowFreqTerm) terms[termOrd]);
             final int[] postings = term.postings;
+            if (hasFreq == false) {
+              LowFreqDocsEnumNoTF docsEnum;
+              if (reuse instanceof LowFreqDocsEnumNoTF) {
+                docsEnum = (LowFreqDocsEnumNoTF) reuse;
+                if (!docsEnum.canReuse(liveDocs)) {
+                  docsEnum = new LowFreqDocsEnumNoTF(liveDocs);
+                }
+              } else {
+                docsEnum = new LowFreqDocsEnumNoTF(liveDocs);
+              }
+
+              return docsEnum.reset(postings);
+              
+            } else if (hasPos == false) {
+              LowFreqDocsEnumNoPos docsEnum;
+              if (reuse instanceof LowFreqDocsEnumNoPos) {
+                docsEnum = (LowFreqDocsEnumNoPos) reuse;
+                if (!docsEnum.canReuse(liveDocs)) {
+                  docsEnum = new LowFreqDocsEnumNoPos(liveDocs);
+                }
+              } else {
+                docsEnum = new LowFreqDocsEnumNoPos(liveDocs);
+              }
+
+              return docsEnum.reset(postings);
+            }
             final byte[] payloads = term.payloads;
             return new LowFreqPostingsEnum(liveDocs, hasOffsets, hasPayloads).reset(postings, payloads);
           } else {
             final HighFreqTerm term = (HighFreqTerm) terms[termOrd];
-            return new HighFreqPostingsEnum(liveDocs, hasOffsets).reset(term.docIDs, term.freqs, term.positions, term.payloads);
+            if (hasPos == false) {
+              return new HighFreqDocsEnum(liveDocs).reset(term.docIDs, term.freqs);
+            } else {
+              return new HighFreqPostingsEnum(liveDocs, hasOffsets).reset(term.docIDs, term.freqs, term.positions, term.payloads);
+            }
           }
         }
 
@@ -1454,10 +1482,9 @@ public final class DirectPostingsFormat
       public PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) {
         // TODO: implement reuse
         // it's hairy!
-        if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-          if (!hasPos) {
-            return null;
-          }
+
+        // TODO: the logic of which enum impl to choose should be refactored to be simpler...
+        if (hasPos && PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
           if (terms[termOrd] instanceof LowFreqTerm) {
             final LowFreqTerm term = ((LowFreqTerm) terms[termOrd]);
             final int[] postings = term.postings;

Modified: lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java (original)
+++ lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java Fri Apr  3 21:27:03 2015
@@ -829,10 +829,9 @@ public final class MemoryPostingsFormat
     @Override
     public PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) {
 
-      if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-        if (field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0) {
-          return null;
-        }
+      // TODO: the logic of which enum impl to choose should be refactored to be simpler...
+      boolean hasPositions = field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
+      if (hasPositions && PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
         boolean hasOffsets = field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
         decodeMetaData();
         FSTPostingsEnum docsAndPositionsEnum;

Modified: lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java (original)
+++ lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java Fri Apr  3 21:27:03 2015
@@ -209,11 +209,8 @@ class SimpleTextFieldsReader extends Fie
     @Override
     public PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) throws IOException {
 
-      if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-        if (indexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0) {
-          // Positions were not indexed
-          return null;
-        }
+      boolean hasPositions = indexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
+      if (hasPositions && PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
 
         SimpleTextPostingsEnum docsAndPositionsEnum;
         if (reuse != null && reuse instanceof SimpleTextPostingsEnum && ((SimpleTextPostingsEnum) reuse).canReuse(SimpleTextFieldsReader.this.in)) {

Modified: lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java (original)
+++ lucene/dev/trunk/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java Fri Apr  3 21:27:03 2015
@@ -388,16 +388,15 @@ public class SimpleTextTermVectorsReader
 
     @Override
     public PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) throws IOException {
-
+      
       if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
         SimpleTVPostings postings = current.getValue();
-        if (postings.positions == null && postings.startOffsets == null) {
-          return null;
+        if (postings.positions != null || postings.startOffsets != null) {
+          // TODO: reuse
+          SimpleTVPostingsEnum e = new SimpleTVPostingsEnum();
+          e.reset(liveDocs, postings.positions, postings.startOffsets, postings.endOffsets, postings.payloads);
+          return e;
         }
-        // TODO: reuse
-        SimpleTVPostingsEnum e = new SimpleTVPostingsEnum();
-        e.reset(liveDocs, postings.positions, postings.startOffsets, postings.endOffsets, postings.payloads);
-        return e;
       }
 
       // TODO: reuse

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingTermVectorsReader.java Fri Apr  3 21:27:03 2015
@@ -936,12 +936,6 @@ public final class CompressingTermVector
 
     @Override
     public final PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) throws IOException {
-
-      if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
-        if (positions == null && startOffsets == null)
-          return null;
-      }
-
       final TVPostingsEnum docsEnum;
       if (reuse != null && reuse instanceof TVPostingsEnum) {
         docsEnum = (TVPostingsEnum) reuse;

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50PostingsReader.java Fri Apr  3 21:27:03 2015
@@ -193,8 +193,12 @@ public final class Lucene50PostingsReade
     
   @Override
   public PostingsEnum postings(FieldInfo fieldInfo, BlockTermState termState, Bits liveDocs, PostingsEnum reuse, int flags) throws IOException {
+    
+    boolean indexHasPositions = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
+    boolean indexHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+    boolean indexHasPayloads = fieldInfo.hasPayloads();
 
-    if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS) == false) {
+    if (indexHasPositions == false || PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS) == false) {
       BlockDocsEnum docsEnum;
       if (reuse instanceof BlockDocsEnum) {
         docsEnum = (BlockDocsEnum) reuse;
@@ -205,17 +209,8 @@ public final class Lucene50PostingsReade
         docsEnum = new BlockDocsEnum(fieldInfo);
       }
       return docsEnum.reset(liveDocs, (IntBlockTermState) termState, flags);
-    }
-
-    boolean indexHasPositions = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
-    boolean indexHasOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
-    boolean indexHasPayloads = fieldInfo.hasPayloads();
-
-    if (!indexHasPositions)
-      return null;
-
-    if ((!indexHasOffsets || PostingsEnum.featureRequested(flags, PostingsEnum.OFFSETS) == false) &&
-        (!indexHasPayloads || PostingsEnum.featureRequested(flags, PostingsEnum.PAYLOADS) == false)) {
+    } else if ((indexHasOffsets == false || PostingsEnum.featureRequested(flags, PostingsEnum.OFFSETS) == false) &&
+               (indexHasPayloads == false || PostingsEnum.featureRequested(flags, PostingsEnum.PAYLOADS) == false)) {
       BlockPostingsEnum docsAndPositionsEnum;
       if (reuse instanceof BlockPostingsEnum) {
         docsAndPositionsEnum = (BlockPostingsEnum) reuse;

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java Fri Apr  3 21:27:03 2015
@@ -1095,8 +1095,7 @@ public class CheckIndex implements Close
     
     final Status.TermIndexStatus status = new Status.TermIndexStatus();
     int computedFieldCount = 0;
-    
-    PostingsEnum docs = null;
+
     PostingsEnum postings = null;
     
     String lastField = null;
@@ -1248,8 +1247,7 @@ public class CheckIndex implements Close
           throw new RuntimeException("docfreq: " + docFreq + " is out of bounds");
         }
         sumDocFreq += docFreq;
-        
-        docs = termsEnum.postings(liveDocs, docs);
+
         postings = termsEnum.postings(liveDocs, postings, PostingsEnum.ALL);
 
         if (hasFreqs == false) {
@@ -1274,18 +1272,11 @@ public class CheckIndex implements Close
           }
         }
         
-        final PostingsEnum docs2;
-        if (postings != null) {
-          docs2 = postings;
-        } else {
-          docs2 = docs;
-        }
-        
         int lastDoc = -1;
         int docCount = 0;
         long totalTermFreq = 0;
         while(true) {
-          final int doc = docs2.nextDoc();
+          final int doc = postings.nextDoc();
           if (doc == DocIdSetIterator.NO_MORE_DOCS) {
             break;
           }
@@ -1293,7 +1284,7 @@ public class CheckIndex implements Close
           visitedDocs.set(doc);
           int freq = -1;
           if (hasFreqs) {
-            freq = docs2.freq();
+            freq = postings.freq();
             if (freq <= 0) {
               throw new RuntimeException("term " + term + ": doc " + doc + ": freq " + freq + " is out of bounds");
             }
@@ -1303,7 +1294,7 @@ public class CheckIndex implements Close
             // When a field didn't index freq, it must
             // consistently "lie" and pretend that freq was
             // 1:
-            if (docs2.freq() != 1) {
+            if (postings.freq() != 1) {
               throw new RuntimeException("term " + term + ": doc " + doc + ": freq " + freq + " != 1 when Terms.hasFreqs() is false");
             }
           }
@@ -1375,20 +1366,20 @@ public class CheckIndex implements Close
         // Re-count if there are deleted docs:
         if (liveDocs != null) {
           if (hasFreqs) {
-            docs = termsEnum.postings(null, docs);
+            postings = termsEnum.postings(null, postings);
             docCount = 0;
             totalTermFreq = 0;
-            while(docs.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
-              visitedDocs.set(docs.docID());
+            while(postings.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
+              visitedDocs.set(postings.docID());
               docCount++;
-              totalTermFreq += docs.freq();
+              totalTermFreq += postings.freq();
             }
           } else {
-            docs = termsEnum.postings(null, docs, PostingsEnum.NONE);
+            postings = termsEnum.postings(null, postings, PostingsEnum.NONE);
             docCount = 0;
             totalTermFreq = -1;
-            while(docs.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
-              visitedDocs.set(docs.docID());
+            while(postings.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
+              visitedDocs.set(postings.docID());
               docCount++;
             }
           }
@@ -1475,15 +1466,15 @@ public class CheckIndex implements Close
         } else {
           for(int idx=0;idx<7;idx++) {
             final int skipDocID = (int) (((idx+1)*(long) maxDoc)/8);
-            docs = termsEnum.postings(liveDocs, docs, PostingsEnum.NONE);
-            final int docID = docs.advance(skipDocID);
+            postings = termsEnum.postings(liveDocs, postings, PostingsEnum.NONE);
+            final int docID = postings.advance(skipDocID);
             if (docID == DocIdSetIterator.NO_MORE_DOCS) {
               break;
             } else {
               if (docID < skipDocID) {
                 throw new RuntimeException("term " + term + ": advance(docID=" + skipDocID + ") returned docID=" + docID);
               }
-              final int nextDocID = docs.nextDoc();
+              final int nextDocID = postings.nextDoc();
               if (nextDocID == DocIdSetIterator.NO_MORE_DOCS) {
                 break;
               }
@@ -1600,12 +1591,12 @@ public class CheckIndex implements Close
                 throw new RuntimeException("seek to existing term " + seekTerms[i] + " returned FOUND but seeked to the wrong term " + termsEnum.term());
               }
               
-              docs = termsEnum.postings(liveDocs, docs, PostingsEnum.NONE);
-              if (docs == null) {
+              postings = termsEnum.postings(liveDocs, postings, PostingsEnum.NONE);
+              if (postings == null) {
                 throw new RuntimeException("null DocsEnum from to existing term " + seekTerms[i]);
               }
-              
-              while(docs.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
+
+              while (postings.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
                 totDocCount++;
               }
             }
@@ -1618,12 +1609,12 @@ public class CheckIndex implements Close
               }
               
               totDocFreq += termsEnum.docFreq();
-              docs = termsEnum.postings(null, docs, PostingsEnum.NONE);
-              if (docs == null) {
+              postings = termsEnum.postings(null, postings, PostingsEnum.NONE);
+              if (postings == null) {
                 throw new RuntimeException("null DocsEnum from to existing term " + seekTerms[i]);
               }
               
-              while(docs.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
+              while(postings.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
                 totDocCountNoDeletes++;
               }
             }
@@ -2022,12 +2013,11 @@ public class CheckIndex implements Close
         infoStream.print("    test: term vectors........");
       }
 
-      PostingsEnum docs = null;
       PostingsEnum postings = null;
 
       // Only used if crossCheckTermVectors is true:
       PostingsEnum postingsDocs = null;
-      PostingsEnum postingsPostings = null;
+      PostingsEnum postingsDocs2 = null;
 
       final Bits liveDocs = reader.getLiveDocs();
 
@@ -2099,67 +2089,43 @@ public class CheckIndex implements Close
                 final boolean hasProx = terms.hasOffsets() || terms.hasPositions();
                 BytesRef term = null;
                 while ((term = termsEnum.next()) != null) {
-                  
-                  if (hasProx) {
-                    postings = termsEnum.postings(null, postings, PostingsEnum.ALL);
-                    assert postings != null;
-                    docs = null;
-                  } else {
-                    docs = termsEnum.postings(null, docs);
-                    assert docs != null;
-                    postings = null;
-                  }
-                  
-                  final PostingsEnum docs2;
-                  if (hasProx) {
-                    assert postings != null;
-                    docs2 = postings;
-                  } else {
-                    assert docs != null;
-                    docs2 = docs;
-                  }
-                  
-                  final PostingsEnum postingsDocs2;
+
+                  // This is the term vectors:
+                  postings = termsEnum.postings(null, postings, PostingsEnum.ALL);
+                  assert postings != null;
+
                   if (!postingsTermsEnum.seekExact(term)) {
                     throw new RuntimeException("vector term=" + term + " field=" + field + " does not exist in postings; doc=" + j);
                   }
-                  postingsPostings = postingsTermsEnum.postings(null, postingsPostings, PostingsEnum.ALL);
-                  if (postingsPostings == null) {
-                    // Term vectors were indexed w/ pos but postings were not
-                    postingsDocs = postingsTermsEnum.postings(null, postingsDocs);
-                    if (postingsDocs == null) {
-                      throw new RuntimeException("vector term=" + term + " field=" + field + " does not exist in postings; doc=" + j);
-                    }
-                  }
-                  
-                  if (postingsPostings != null) {
-                    postingsDocs2 = postingsPostings;
-                  } else {
-                    postingsDocs2 = postingsDocs;
-                  }
+
+                  // This is the inverted index ("real" postings):
+                  postingsDocs2 = postingsTermsEnum.postings(null, postingsDocs2, PostingsEnum.ALL);
+                  assert postingsDocs2 != null;
+
                   
                   final int advanceDoc = postingsDocs2.advance(j);
                   if (advanceDoc != j) {
                     throw new RuntimeException("vector term=" + term + " field=" + field + ": doc=" + j + " was not found in postings (got: " + advanceDoc + ")");
                   }
                   
-                  final int doc = docs2.nextDoc();
+                  final int doc = postings.nextDoc();
                   
                   if (doc != 0) {
                     throw new RuntimeException("vector for doc " + j + " didn't return docID=0: got docID=" + doc);
                   }
                   
                   if (postingsHasFreq) {
-                    final int tf = docs2.freq();
+                    final int tf = postings.freq();
                     if (postingsHasFreq && postingsDocs2.freq() != tf) {
                       throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + ": freq=" + tf + " differs from postings freq=" + postingsDocs2.freq());
                     }
-                    
+
+                    // Term vectors has prox?
                     if (hasProx) {
                       for (int i = 0; i < tf; i++) {
                         int pos = postings.nextPosition();
-                        if (postingsPostings != null) {
-                          int postingsPos = postingsPostings.nextPosition();
+                        if (postingsTerms.hasPositions()) {
+                          int postingsPos = postingsDocs2.nextPosition();
                           if (terms.hasPositions() && pos != postingsPos) {
                             throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + ": pos=" + pos + " differs from postings pos=" + postingsPos);
                           }
@@ -2179,19 +2145,18 @@ public class CheckIndex implements Close
                         }
                         lastStartOffset = startOffset;
                          */
-                        
-                        if (postingsPostings != null) {
-                          final int postingsStartOffset = postingsPostings.startOffset();
-                          
-                          final int postingsEndOffset = postingsPostings.endOffset();
-                          if (startOffset != -1 && postingsStartOffset != -1 && startOffset != postingsStartOffset) {
+
+                        if (startOffset != -1 && endOffset != -1 && postingsTerms.hasOffsets()) {
+                          int postingsStartOffset = postingsDocs2.startOffset();
+                          int postingsEndOffset = postingsDocs2.endOffset();
+                          if (startOffset != postingsStartOffset) {
                             throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + ": startOffset=" + startOffset + " differs from postings startOffset=" + postingsStartOffset);
                           }
-                          if (endOffset != -1 && postingsEndOffset != -1 && endOffset != postingsEndOffset) {
+                          if (endOffset != postingsEndOffset) {
                             throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + ": endOffset=" + endOffset + " differs from postings endOffset=" + postingsEndOffset);
                           }
                         }
-                        
+
                         BytesRef payload = postings.getPayload();
                         
                         if (payload != null) {
@@ -2199,21 +2164,20 @@ public class CheckIndex implements Close
                         }
                         
                         if (postingsHasPayload && vectorsHasPayload) {
-                          assert postingsPostings != null;
                           
                           if (payload == null) {
                             // we have payloads, but not at this position. 
                             // postings has payloads too, it should not have one at this position
-                            if (postingsPostings.getPayload() != null) {
-                              throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + " has no payload but postings does: " + postingsPostings.getPayload());
+                            if (postingsDocs2.getPayload() != null) {
+                              throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + " has no payload but postings does: " + postingsDocs2.getPayload());
                             }
                           } else {
                             // we have payloads, and one at this position
                             // postings should also have one at this position, with the same bytes.
-                            if (postingsPostings.getPayload() == null) {
+                            if (postingsDocs2.getPayload() == null) {
                               throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + " has payload=" + payload + " but postings does not.");
                             }
-                            BytesRef postingsPayload = postingsPostings.getPayload();
+                            BytesRef postingsPayload = postingsDocs2.getPayload();
                             if (!payload.equals(postingsPayload)) {
                               throw new RuntimeException("vector term=" + term + " field=" + field + " doc=" + j + " has payload=" + payload + " but differs from postings payload=" + postingsPayload);
                             }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java Fri Apr  3 21:27:03 2015
@@ -222,17 +222,17 @@ public class FilterLeafReader extends Le
   }
 
   /** Base class for filtering {@link PostingsEnum} implementations. */
-  public static class FilterDocsEnum extends PostingsEnum {
-    /** The underlying DocsEnum instance. */
+  public static class FilterPostingsEnum extends PostingsEnum {
+    /** The underlying PostingsEnum instance. */
     protected final PostingsEnum in;
 
     /**
-     * Create a new FilterDocsEnum
-     * @param in the underlying DocsEnum instance.
+     * Create a new FilterPostingsEnum
+     * @param in the underlying PostingsEnum instance.
      */
-    public FilterDocsEnum(PostingsEnum in) {
+    public FilterPostingsEnum(PostingsEnum in) {
       if (in == null) {
-        throw new NullPointerException("incoming DocsEnum cannot be null");
+        throw new NullPointerException("incoming PostingsEnum cannot be null");
       }
       this.in = in;
     }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/LeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/LeafReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/LeafReader.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/LeafReader.java Fri Apr  3 21:27:03 2015
@@ -223,7 +223,14 @@ public abstract class LeafReader extends
   }
 
   /** Returns {@link PostingsEnum} for the specified term
-   *  with {@link PostingsEnum#FREQS}. */
+   *  with {@link PostingsEnum#FREQS}.
+   *  <p>
+   *  Use this method if you only require documents and frequencies,
+   *  and do not need any proximity data.
+   *  This method is equivalent to 
+   *  {@link #postings(Term, int) postings(term, PostingsEnum.FREQS)}
+   *  @see #postings(Term, int)
+   */
   public final PostingsEnum postings(Term term) throws IOException {
     return postings(term, PostingsEnum.FREQS);
   }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiFields.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiFields.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiFields.java Fri Apr  3 21:27:03 2015
@@ -159,8 +159,7 @@ public final class MultiFields extends F
    *  required.  Some codecs may be able to optimize
    *  their implementation when offsets and/or payloads are not
    *  required. This will return null if the field or term does not
-   *  exist or positions were not indexed. See {@link
-   *  TermsEnum#postings(Bits, PostingsEnum,int)}. */
+   *  exist. See {@link TermsEnum#postings(Bits, PostingsEnum,int)}. */
   public static PostingsEnum getTermPositionsEnum(IndexReader r, Bits liveDocs, String field, BytesRef term, int flags) throws IOException {
     assert field != null;
     assert term != null;

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/MultiTermsEnum.java Fri Apr  3 21:27:03 2015
@@ -379,22 +379,14 @@ public final class MultiTermsEnum extend
 
       assert entry.index < docsEnum.subPostingsEnums.length: entry.index + " vs " + docsEnum.subPostingsEnums.length + "; " + subs.length;
       final PostingsEnum subPostingsEnum = entry.terms.postings(b, docsEnum.subPostingsEnums[entry.index], flags);
-      if (subPostingsEnum != null) {
-        docsEnum.subPostingsEnums[entry.index] = subPostingsEnum;
-        subDocs[upto].postingsEnum = subPostingsEnum;
-        subDocs[upto].slice = entry.subSlice;
-        upto++;
-      } else {
-        // should this be an error?
-        return null;    // We can't support what is being asked for
-      }
-    }
-
-    if (upto == 0) {
-      return null;
-    } else {
-      return docsEnum.reset(subDocs, upto);
+      assert subPostingsEnum != null;
+      docsEnum.subPostingsEnums[entry.index] = subPostingsEnum;
+      subDocs[upto].postingsEnum = subPostingsEnum;
+      subDocs[upto].slice = entry.subSlice;
+      upto++;
     }
+    
+    return docsEnum.reset(subDocs, upto);
   }
 
   final static class TermsEnumWithSlice {

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java Fri Apr  3 21:27:03 2015
@@ -141,10 +141,17 @@ public abstract class TermsEnum implemen
   /** Get {@link PostingsEnum} for the current term.  Do not
    *  call this when the enum is unpositioned.  This method
    *  will not return null.
+   *  <p>
+   *  Use this method if you only require documents and frequencies,
+   *  and do not need any proximity data.
+   *  This method is equivalent to 
+   *  {@link #postings(Bits, PostingsEnum, int) postings(liveDocs, reuse, PostingsEnum.FREQS)}
    *  
    * @param liveDocs unset bits are documents that should not
    * be returned
-   * @param reuse pass a prior PostingsEnum for possible reuse */
+   * @param reuse pass a prior PostingsEnum for possible reuse 
+   * @see #postings(Bits, PostingsEnum, int)
+   */
   public final PostingsEnum postings(Bits liveDocs, PostingsEnum reuse) throws IOException {
     return postings(liveDocs, reuse, PostingsEnum.FREQS);
   }
@@ -160,7 +167,7 @@ public abstract class TermsEnum implemen
    * @param reuse pass a prior PostingsEnum for possible reuse
    * @param flags specifies which optional per-document values
    *        you require; see {@link PostingsEnum#FREQS}
-   * @see #postings(Bits, PostingsEnum, int) */
+   */
   public abstract PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) throws IOException;
 
   /**

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java Fri Apr  3 21:27:03 2015
@@ -190,6 +190,11 @@ public class MultiPhraseQuery extends Qu
         return null;
       }
 
+      // TODO: move this check to createWeight to happen earlier to the user?
+      if (fieldTerms.hasPositions() == false) {
+        throw new IllegalStateException("field \"" + field + "\" was indexed without position data; cannot run MultiPhraseQuery (phrase=" + getQuery() + ")");
+      }
+
       // Reuse single TermsEnum below:
       final TermsEnum termsEnum = fieldTerms.iterator(null);
 
@@ -230,12 +235,6 @@ public class MultiPhraseQuery extends Qu
           termsEnum.seekExact(term.bytes(), termState);
           postingsEnum = termsEnum.postings(liveDocs, null, PostingsEnum.POSITIONS);
 
-          if (postingsEnum == null) {
-            // term does exist, but has no positions
-            assert termsEnum.postings(liveDocs, null, PostingsEnum.NONE) != null: "termstate found but no term exists in reader";
-            throw new IllegalStateException("field \"" + term.field() + "\" was indexed without position data; cannot run PhraseQuery (term=" + term.text() + ")");
-          }
-
           docFreq = termsEnum.docFreq();
         }
 
@@ -482,10 +481,6 @@ class UnionPostingsEnum extends Postings
       }
       termsEnum.seekExact(term.bytes(), termState);
       PostingsEnum postings = termsEnum.postings(liveDocs, null, PostingsEnum.POSITIONS);
-      if (postings == null) {
-        // term does exist, but has no positions
-        throw new IllegalStateException("field \"" + term.field() + "\" was indexed without position data; cannot run PhraseQuery (term=" + term.text() + ")");
-      }
       cost += postings.cost();
       postingsEnums.add(postings);
     }

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java Fri Apr  3 21:27:03 2015
@@ -297,6 +297,10 @@ public class PhraseQuery extends Query {
         return null;
       }
 
+      if (fieldTerms.hasPositions() == false) {
+        throw new IllegalStateException("field \"" + field + "\" was indexed without position data; cannot run PhraseQuery (phrase=" + getQuery() + ")");
+      }
+
       // Reuse single TermsEnum below:
       final TermsEnum te = fieldTerms.iterator(null);
       
@@ -309,14 +313,6 @@ public class PhraseQuery extends Query {
         }
         te.seekExact(t.bytes(), state);
         PostingsEnum postingsEnum = te.postings(liveDocs, null, PostingsEnum.POSITIONS);
-
-        // PhraseQuery on a field that did not index
-        // positions.
-        if (postingsEnum == null) {
-          assert te.seekExact(t.bytes()) : "termstate found but no term exists in reader";
-          // term does exist, but has no positions
-          throw new IllegalStateException("field \"" + t.field() + "\" was indexed without position data; cannot run PhraseQuery (term=" + t.text() + ")");
-        }
         postingsFreqs[i] = new PostingsAndFreq(postingsEnum, te.docFreq(), positions.get(i), t);
       }
 

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java Fri Apr  3 21:27:03 2015
@@ -94,6 +94,10 @@ public class SpanTermQuery extends SpanQ
       // so we seek to the term now in this segment..., this sucks because it's ugly mostly!
       final Terms terms = context.reader().terms(term.field());
       if (terms != null) {
+        if (terms.hasPositions() == false) {
+          throw new IllegalStateException("field \"" + term.field() + "\" was indexed without position data; cannot run SpanTermQuery (term=" + term.text() + ")");
+        }
+
         final TermsEnum termsEnum = terms.iterator(null);
         if (termsEnum.seekExact(term.bytes())) {
           state = termsEnum.termState();
@@ -115,12 +119,6 @@ public class SpanTermQuery extends SpanQ
     termsEnum.seekExact(term.bytes(), state);
 
     final PostingsEnum postings = termsEnum.postings(acceptDocs, null, PostingsEnum.PAYLOADS);
-
-    if (postings != null) {
-      return new TermSpans(postings, term);
-    } else {
-      // term does exist, but has no positions
-      throw new IllegalStateException("field \"" + term.field() + "\" was indexed without position data; cannot run SpanTermQuery (term=" + term.text() + ")");
-    }
+    return new TermSpans(postings, term);
   }
 }

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java Fri Apr  3 21:27:03 2015
@@ -172,9 +172,10 @@ public class TestBlockPostingsFormat3 ex
     
     // NOTE: we don't assert hasOffsets/hasPositions/hasPayloads because they are allowed to be different
 
+    boolean bothHavePositions = leftTerms.hasPositions() && rightTerms.hasPositions();
     TermsEnum leftTermsEnum = leftTerms.iterator(null);
     TermsEnum rightTermsEnum = rightTerms.iterator(null);
-    assertTermsEnum(leftTermsEnum, rightTermsEnum, true);
+    assertTermsEnum(leftTermsEnum, rightTermsEnum, true, bothHavePositions);
     
     assertTermsSeeking(leftTerms, rightTerms);
     
@@ -187,7 +188,7 @@ public class TestBlockPostingsFormat3 ex
           // TODO: test start term too
           TermsEnum leftIntersection = leftTerms.intersect(automaton, null);
           TermsEnum rightIntersection = rightTerms.intersect(automaton, null);
-          assertTermsEnum(leftIntersection, rightIntersection, rarely());
+          assertTermsEnum(leftIntersection, rightIntersection, rarely(), bothHavePositions);
         }
       }
     }
@@ -280,7 +281,7 @@ public class TestBlockPostingsFormat3 ex
    * checks the terms enum sequentially
    * if deep is false, it does a 'shallow' test that doesnt go down to the docsenums
    */
-  public void assertTermsEnum(TermsEnum leftTermsEnum, TermsEnum rightTermsEnum, boolean deep) throws Exception {
+  public void assertTermsEnum(TermsEnum leftTermsEnum, TermsEnum rightTermsEnum, boolean deep, boolean hasPositions) throws Exception {
     BytesRef term;
     Bits randomBits = new RandomBits(MAXDOC, random().nextDouble(), random());
     PostingsEnum leftPositions = null;
@@ -292,56 +293,58 @@ public class TestBlockPostingsFormat3 ex
       assertEquals(term, rightTermsEnum.next());
       assertTermStats(leftTermsEnum, rightTermsEnum);
       if (deep) {
-        // with payloads + off
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.ALL),
-                                   rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.ALL));
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.ALL),
-                                   rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.ALL));
-
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.ALL),
-                                rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.ALL));
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.ALL),
-                                rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.ALL));
-        // with payloads only
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.PAYLOADS),
-                                   rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.PAYLOADS));
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.PAYLOADS),
-                                   rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.PAYLOADS));
-
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.PAYLOADS),
-                                rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.PAYLOADS));
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.PAYLOADS),
-                                rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.PAYLOADS));
-
-        // with offsets only
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.OFFSETS),
-                                   rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.OFFSETS));
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.OFFSETS),
-                                   rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.OFFSETS));
-
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.OFFSETS),
-                                rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.OFFSETS));
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.OFFSETS),
-                                rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.OFFSETS));
-        
-        // with positions only
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.POSITIONS),
-                                   rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.POSITIONS));
-        assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.POSITIONS),
-                                   rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.POSITIONS));
-
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.POSITIONS),
-                                rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.POSITIONS));
-        assertPositionsSkipping(leftTermsEnum.docFreq(), 
-                                leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.POSITIONS),
-                                rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.POSITIONS));
+        if (hasPositions) {
+          // with payloads + off
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.ALL),
+                                     rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.ALL));
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.ALL),
+                                     rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.ALL));
+
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.ALL),
+                                  rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.ALL));
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.ALL),
+                                  rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.ALL));
+          // with payloads only
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.PAYLOADS),
+                                     rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.PAYLOADS));
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.PAYLOADS),
+                                     rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.PAYLOADS));
+
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.PAYLOADS),
+                                  rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.PAYLOADS));
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.PAYLOADS),
+                                  rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.PAYLOADS));
+
+          // with offsets only
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.OFFSETS),
+                                     rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.OFFSETS));
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.OFFSETS),
+                                     rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.OFFSETS));
+
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.OFFSETS),
+                                  rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.OFFSETS));
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.OFFSETS),
+                                  rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.OFFSETS));
+
+          // with positions only
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.POSITIONS),
+                                     rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.POSITIONS));
+          assertDocsAndPositionsEnum(leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.POSITIONS),
+                                     rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.POSITIONS));
+
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(null, leftPositions, PostingsEnum.POSITIONS),
+                                  rightPositions = rightTermsEnum.postings(null, rightPositions, PostingsEnum.POSITIONS));
+          assertPositionsSkipping(leftTermsEnum.docFreq(),
+                                  leftPositions = leftTermsEnum.postings(randomBits, leftPositions, PostingsEnum.POSITIONS),
+                                  rightPositions = rightTermsEnum.postings(randomBits, rightPositions, PostingsEnum.POSITIONS));
+        }
         
         // with freqs:
         assertDocsEnum(leftDocs = leftTermsEnum.postings(null, leftDocs),
@@ -389,11 +392,8 @@ public class TestBlockPostingsFormat3 ex
    * checks docs + freqs + positions + payloads, sequentially
    */
   public void assertDocsAndPositionsEnum(PostingsEnum leftDocs, PostingsEnum rightDocs) throws Exception {
-    if (leftDocs == null || rightDocs == null) {
-      assertNull(leftDocs);
-      assertNull(rightDocs);
-      return;
-    }
+    assertNotNull(leftDocs);
+    assertNotNull(rightDocs);
     assertEquals(-1, leftDocs.docID());
     assertEquals(-1, rightDocs.docID());
     int docid;

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java Fri Apr  3 21:27:03 2015
@@ -452,20 +452,15 @@ public class TestCodecs extends LuceneTe
         do {
           term = field.terms[upto];
           if (random().nextInt(3) == 1) {
-            final PostingsEnum docs;
             final PostingsEnum postings;
             if (!field.omitTF) {
+              // TODO: we should randomize which postings features are available, but
+              // need to coordinate this with the checks below that rely on such features
               postings = termsEnum.postings(null, null, PostingsEnum.ALL);
-              if (postings != null) {
-                docs = postings;
-              } else {
-                docs = TestUtil.docs(random(), termsEnum, null, null, PostingsEnum.FREQS);
-              }
             } else {
-              postings = null;
-              docs = TestUtil.docs(random(), termsEnum, null, null, PostingsEnum.NONE);
+              postings = TestUtil.docs(random(), termsEnum, null, null, PostingsEnum.FREQS);
             }
-            assertNotNull(docs);
+            assertNotNull(postings);
             int upto2 = -1;
             boolean ended = false;
             while(upto2 < term.docs.length-1) {
@@ -476,10 +471,10 @@ public class TestCodecs extends LuceneTe
                 final int inc = 1+random().nextInt(left-1);
                 upto2 += inc;
                 if (random().nextInt(2) == 1) {
-                  doc = docs.advance(term.docs[upto2]);
+                  doc = postings.advance(term.docs[upto2]);
                   assertEquals(term.docs[upto2], doc);
                 } else {
-                  doc = docs.advance(1+term.docs[upto2]);
+                  doc = postings.advance(1+term.docs[upto2]);
                   if (doc == DocIdSetIterator.NO_MORE_DOCS) {
                     // skipped past last doc
                     assert upto2 == term.docs.length-1;
@@ -494,7 +489,7 @@ public class TestCodecs extends LuceneTe
                   }
                 }
               } else {
-                doc = docs.nextDoc();
+                doc = postings.nextDoc();
                 assertTrue(doc != -1);
                 upto2++;
               }
@@ -508,7 +503,7 @@ public class TestCodecs extends LuceneTe
             }
 
             if (!ended) {
-              assertEquals(DocIdSetIterator.NO_MORE_DOCS, docs.nextDoc());
+              assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
             }
           }
           upto++;

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java Fri Apr  3 21:27:03 2015
@@ -77,12 +77,12 @@ public class TestFilterLeafReader extend
 
       @Override
       public PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, int flags) throws IOException {
-        return new TestPositions(super.postings(liveDocs, reuse == null ? null : ((FilterDocsEnum) reuse).in, flags));
+        return new TestPositions(super.postings(liveDocs, reuse == null ? null : ((FilterPostingsEnum) reuse).in, flags));
       }
     }
 
     /** Filter that only returns odd numbered documents. */
-    private static class TestPositions extends FilterDocsEnum {
+    private static class TestPositions extends FilterPostingsEnum {
       public TestPositions(PostingsEnum in) {
         super(in);
       }
@@ -188,7 +188,7 @@ public class TestFilterLeafReader extend
     checkOverrideMethods(FilterLeafReader.FilterFields.class);
     checkOverrideMethods(FilterLeafReader.FilterTerms.class);
     checkOverrideMethods(FilterLeafReader.FilterTermsEnum.class);
-    checkOverrideMethods(FilterLeafReader.FilterDocsEnum.class);
+    checkOverrideMethods(FilterLeafReader.FilterPostingsEnum.class);
   }
 
   public void testUnwrap() throws IOException {

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitPositions.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitPositions.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitPositions.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestOmitPositions.java Fri Apr  3 21:27:03 2015
@@ -51,7 +51,7 @@ public class TestOmitPositions extends L
     IndexReader reader = w.getReader();
     w.close();
     
-    assertNull(MultiFields.getTermPositionsEnum(reader, null, "foo", new BytesRef("test")));
+    assertNotNull(MultiFields.getTermPositionsEnum(reader, null, "foo", new BytesRef("test")));
     
     PostingsEnum de = TestUtil.docs(random(), reader, "foo", new BytesRef("test"), null, null, PostingsEnum.FREQS);
     while (de.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestStressIndexing2.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestStressIndexing2.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestStressIndexing2.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestStressIndexing2.java Fri Apr  3 21:27:03 2015
@@ -26,7 +26,6 @@ import java.util.Map;
 import java.util.Random;
 
 import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
@@ -397,7 +396,7 @@ public class TestStressIndexing2 extends
             while((term2 = termsEnum3.next()) != null) {
               System.out.println("      " + term2.utf8ToString() + ": freq=" + termsEnum3.totalTermFreq());
               dpEnum = termsEnum3.postings(null, dpEnum, PostingsEnum.ALL);
-              if (dpEnum != null) {
+              if (terms3.hasPositions()) {
                 assertTrue(dpEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
                 final int freq = dpEnum.freq();
                 System.out.println("        doc=" + dpEnum.docID() + " freq=" + freq);
@@ -620,8 +619,9 @@ public class TestStressIndexing2 extends
         
         dpEnum1 = termsEnum1.postings(null, dpEnum1, PostingsEnum.ALL);
         dpEnum2 = termsEnum2.postings(null, dpEnum2, PostingsEnum.ALL);
-        if (dpEnum1 != null) {
-          assertNotNull(dpEnum2);
+
+        if (terms1.hasPositions()) {
+          assertTrue(terms2.hasPositions());
           int docID1 = dpEnum1.nextDoc();
           dpEnum2.nextDoc();
           // docIDs are not supposed to be equal
@@ -632,24 +632,17 @@ public class TestStressIndexing2 extends
           int freq1 = dpEnum1.freq();
           int freq2 = dpEnum2.freq();
           assertEquals(freq1, freq2);
-          OffsetAttribute offsetAtt1 = dpEnum1.attributes().getAttribute(OffsetAttribute.class);
-          OffsetAttribute offsetAtt2 = dpEnum2.attributes().getAttribute(OffsetAttribute.class);
-
-          if (offsetAtt1 != null) {
-            assertNotNull(offsetAtt2);
-          } else {
-            assertNull(offsetAtt2);
-          }
 
           for(int posUpto=0;posUpto<freq1;posUpto++) {
             int pos1 = dpEnum1.nextPosition();
             int pos2 = dpEnum2.nextPosition();
             assertEquals(pos1, pos2);
-            if (offsetAtt1 != null) {
-              assertEquals(offsetAtt1.startOffset(),
-                           offsetAtt2.startOffset());
-              assertEquals(offsetAtt1.endOffset(),
-                           offsetAtt2.endOffset());
+            if (terms1.hasOffsets()) {
+              assertTrue(terms2.hasOffsets());
+              assertEquals(dpEnum1.startOffset(),
+                           dpEnum2.startOffset());
+              assertEquals(dpEnum1.endOffset(),
+                           dpEnum2.endOffset());
             }
           }
           assertEquals(DocIdSetIterator.NO_MORE_DOCS, dpEnum1.nextDoc());

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsReader.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsReader.java Fri Apr  3 21:27:03 2015
@@ -292,7 +292,7 @@ public class TestTermVectorsReader exten
       //System.out.println("Term: " + term);
       assertEquals(testTerms[i], term);
       assertNotNull(termsEnum.postings(null, null));
-      assertNull(termsEnum.postings(null, null, PostingsEnum.ALL)); // no pos
+      assertNotNull(termsEnum.postings(null, null, PostingsEnum.ALL));
     }
     reader.close();
   }

Modified: lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java (original)
+++ lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java Fri Apr  3 21:27:03 2015
@@ -504,6 +504,10 @@ public class PostingsHighlighter {
       // if the segment has changed, we must initialize new enums.
       if (leaf != lastLeaf) {
         Terms t = r.terms(field);
+        if (!t.hasOffsets()) {
+          // no offsets available
+          throw new IllegalArgumentException("field '" + field + "' was indexed without offsets, cannot highlight");
+        }
         if (t != null) {
           termsEnum = t.iterator(null);
           postings = new PostingsEnum[terms.length];
@@ -560,10 +564,7 @@ public class PostingsHighlighter {
           continue; // term not found
         }
         de = postings[i] = termsEnum.postings(null, null, PostingsEnum.OFFSETS);
-        if (de == null) {
-          // no positions available
-          throw new IllegalArgumentException("field '" + field + "' was indexed without offsets, cannot highlight");
-        }
+        assert de != null;
         pDoc = de.advance(doc);
       } else {
         pDoc = de.docID();
@@ -599,9 +600,7 @@ public class PostingsHighlighter {
     while ((off = pq.poll()) != null) {
       final PostingsEnum dp = off.dp;
       int start = dp.startOffset();
-      if (start == -1) {
-        throw new IllegalArgumentException("field '" + field + "' was indexed without offsets, cannot highlight");
-      }
+      assert start >= 0;
       int end = dp.endOffset();
       // LUCENE-5166: this hit would span the content limit... however more valid 
       // hits may exist (they are sorted by start). so we pretend like we never 

Modified: lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java (original)
+++ lucene/dev/trunk/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldTermStack.java Fri Apr  3 21:27:03 2015
@@ -86,7 +86,7 @@ public class FieldTermStack {
     }
 
     final Terms vector = vectors.terms(fieldName);
-    if (vector == null) {
+    if (vector == null || vector.hasPositions() == false) {
       // null snippet
       return;
     }
@@ -105,11 +105,6 @@ public class FieldTermStack {
         continue;
       }
       dpEnum = termsEnum.postings(null, dpEnum, PostingsEnum.POSITIONS);
-      if (dpEnum == null) {
-        // null snippet
-        return;
-      }
-
       dpEnum.nextDoc();
       
       // For weight look here: http://lucene.apache.org/core/3_6_0/api/core/org/apache/lucene/search/DefaultSimilarity.html

Modified: lucene/dev/trunk/lucene/misc/src/java/org/apache/lucene/index/SortingLeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/misc/src/java/org/apache/lucene/index/SortingLeafReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/misc/src/java/org/apache/lucene/index/SortingLeafReader.java (original)
+++ lucene/dev/trunk/lucene/misc/src/java/org/apache/lucene/index/SortingLeafReader.java Fri Apr  3 21:27:03 2015
@@ -88,13 +88,13 @@ public class SortingLeafReader extends F
 
     @Override
     public TermsEnum iterator(final TermsEnum reuse) throws IOException {
-      return new SortingTermsEnum(in.iterator(reuse), docMap, indexOptions);
+      return new SortingTermsEnum(in.iterator(reuse), docMap, indexOptions, hasPositions());
     }
 
     @Override
     public TermsEnum intersect(CompiledAutomaton compiled, BytesRef startTerm)
         throws IOException {
-      return new SortingTermsEnum(in.intersect(compiled, startTerm), docMap, indexOptions);
+      return new SortingTermsEnum(in.intersect(compiled, startTerm), docMap, indexOptions, hasPositions());
     }
 
   }
@@ -103,11 +103,13 @@ public class SortingLeafReader extends F
 
     final Sorter.DocMap docMap; // pkg-protected to avoid synthetic accessor methods
     private final IndexOptions indexOptions;
+    private final boolean hasPositions;
 
-    public SortingTermsEnum(final TermsEnum in, Sorter.DocMap docMap, IndexOptions indexOptions) {
+    public SortingTermsEnum(final TermsEnum in, Sorter.DocMap docMap, IndexOptions indexOptions, boolean hasPositions) {
       super(in);
       this.docMap = docMap;
       this.indexOptions = indexOptions;
+      this.hasPositions = hasPositions;
     }
 
     Bits newToOld(final Bits liveDocs) {
@@ -132,7 +134,7 @@ public class SortingLeafReader extends F
     @Override
     public PostingsEnum postings(Bits liveDocs, PostingsEnum reuse, final int flags) throws IOException {
 
-      if (PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
+      if (hasPositions && PostingsEnum.featureRequested(flags, PostingsEnum.POSITIONS)) {
         final PostingsEnum inReuse;
         final SortingPostingsEnum wrapReuse;
         if (reuse != null && reuse instanceof SortingPostingsEnum) {
@@ -146,10 +148,6 @@ public class SortingLeafReader extends F
         }
 
         final PostingsEnum inDocsAndPositions = in.postings(newToOld(liveDocs), inReuse, flags);
-        if (inDocsAndPositions == null) {
-          return null;
-        }
-
         // we ignore the fact that offsets may be stored but not asked for,
         // since this code is expected to be used during addIndexes which will
         // ask for everything. if that assumption changes in the future, we can
@@ -328,7 +326,7 @@ public class SortingLeafReader extends F
     }
   }
 
-  static class SortingDocsEnum extends FilterDocsEnum {
+  static class SortingDocsEnum extends FilterPostingsEnum {
 
     private static final class DocFreqSorter extends TimSorter {
 
@@ -489,9 +487,31 @@ public class SortingLeafReader extends F
     PostingsEnum getWrapped() {
       return in;
     }
+    
+    // we buffer up docs/freqs only, don't forward any positions requests to underlying enum
+
+    @Override
+    public int nextPosition() throws IOException {
+      return -1;
+    }
+
+    @Override
+    public int startOffset() throws IOException {
+      return -1;
+    }
+
+    @Override
+    public int endOffset() throws IOException {
+      return -1;
+    }
+
+    @Override
+    public BytesRef getPayload() throws IOException {
+      return null;
+    }
   }
 
-  static class SortingPostingsEnum extends FilterDocsEnum {
+  static class SortingPostingsEnum extends FilterPostingsEnum {
 
     /**
      * A {@link TimSorter} which sorts two parallel arrays of doc IDs and

Modified: lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java?rev=1671163&r1=1671162&r2=1671163&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java (original)
+++ lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java Fri Apr  3 21:27:03 2015
@@ -159,9 +159,8 @@ public class AssertingLeafReader extends
         actualReuse = null;
       }
       PostingsEnum docs = super.postings(liveDocs, actualReuse, flags);
-      if (docs == null) {
-        return null;
-      } else if (docs == actualReuse) {
+      assert docs != null;
+      if (docs == actualReuse) {
         // codec reused, reset asserting state
         ((AssertingPostingsEnum)reuse).reset();
         return reuse;
@@ -282,7 +281,7 @@ public class AssertingLeafReader extends
   static enum DocsEnumState { START, ITERATING, FINISHED };
 
   /** Wraps a docsenum with additional checks */
-  public static class AssertingPostingsEnum extends FilterDocsEnum {
+  public static class AssertingPostingsEnum extends FilterPostingsEnum {
     private final Thread creationThread = Thread.currentThread();
     private DocsEnumState state = DocsEnumState.START;
     int positionCount = 0;