You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ry...@apache.org on 2011/03/25 22:26:34 UTC

svn commit: r1085564 - in /lucene/dev/trunk/solr/src: java/org/apache/solr/handler/ java/org/apache/solr/handler/component/ java/org/apache/solr/response/ java/org/apache/solr/response/transform/ java/org/apache/solr/search/ java/org/apache/solr/util/ ...

Author: ryan
Date: Fri Mar 25 21:26:33 2011
New Revision: 1085564

URL: http://svn.apache.org/viewvc?rev=1085564&view=rev
Log:
SOLR-2444 -- moving ReturnFields to search package.  Integrating yoniks basic parsing.
(should also fix regression)

Added:
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java   (with props)
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java
      - copied, changed from r1085451, lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocValuesAugmenter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java
      - copied, changed from r1085451, lucene/dev/trunk/solr/src/java/org/apache/solr/response/ReturnFields.java
Removed:
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/ReturnFields.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocValuesAugmenter.java
Modified:
    lucene/dev/trunk/solr/src/java/org/apache/solr/handler/MoreLikeThisHandler.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/BaseResponseWriter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/BinaryResponseWriter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/CSVResponseWriter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/JSONResponseWriter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/PHPSerializedResponseWriter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/SolrQueryResponse.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/TextResponseWriter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/XMLWriter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/util/SolrPluginUtils.java
    lucene/dev/trunk/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java
    lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/handler/MoreLikeThisHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/handler/MoreLikeThisHandler.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/handler/MoreLikeThisHandler.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/handler/MoreLikeThisHandler.java Fri Mar 25 21:26:33 2011
@@ -47,7 +47,6 @@ import org.apache.solr.common.util.Simpl
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SimpleFacets;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.response.ReturnFields;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
@@ -78,10 +77,10 @@ public class MoreLikeThisHandler extends
     SolrParams params = req.getParams();
 
     // Set field flags
-    ReturnFields returnFields = ReturnFields.getReturnFields( req );
+    ReturnFields returnFields = new ReturnFields( req );
     rsp.setReturnFields( returnFields );
     int flags = 0;
-    if (returnFields.getWantsScore()) {
+    if (returnFields.wantsScore()) {
       flags |= SolrIndexSearcher.GET_SCORES;
     }
 

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java Fri Mar 25 21:26:33 2011
@@ -40,7 +40,6 @@ import org.apache.solr.common.util.StrUt
 import org.apache.solr.core.CoreDescriptor;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.ResultContext;
-import org.apache.solr.response.ReturnFields;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.FieldType;
 import org.apache.solr.schema.SchemaField;
@@ -75,10 +74,10 @@ public class QueryComponent extends Sear
     SolrQueryResponse rsp = rb.rsp;
 
     // Set field flags    
-    ReturnFields returnFields = ReturnFields.getReturnFields( req );
+    ReturnFields returnFields = new ReturnFields( req );
     rsp.setReturnFields( returnFields );
     int flags = 0;
-    if (returnFields.getWantsScore()) {
+    if (returnFields.wantsScore()) {
       flags |= SolrIndexSearcher.GET_SCORES;
     }
     rb.setFieldFlags( flags );

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/BaseResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/BaseResponseWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/BaseResponseWriter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/BaseResponseWriter.java Fri Mar 25 21:26:33 2011
@@ -24,6 +24,7 @@ import org.apache.solr.common.SolrInputD
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.search.DocList;
+import org.apache.solr.search.ReturnFields;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.search.DocIterator;
 import org.apache.solr.schema.FieldType;
@@ -156,7 +157,7 @@ public abstract class BaseResponseWriter
     SolrDocument solrDoc = new SolrDocument();
     for (Fieldable f : doc.getFields()) {
       String fieldName = f.name();
-      if (info.returnFields != null && !info.returnFields.contains(fieldName))
+      if (info.returnFields != null && !info.returnFields.wantsField(fieldName))
         continue;
       SchemaField sf = info.schema.getFieldOrNull(fieldName);
       FieldType ft = null;

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/BinaryResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/BinaryResponseWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/BinaryResponseWriter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/BinaryResponseWriter.java Fri Mar 25 21:26:33 2011
@@ -28,6 +28,7 @@ import org.apache.solr.response.transfor
 import org.apache.solr.response.transform.TransformContext;
 import org.apache.solr.schema.*;
 import org.apache.solr.search.DocList;
+import org.apache.solr.search.ReturnFields;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -92,7 +93,7 @@ public class BinaryResponseWriter implem
         // This typically happens when distributed search adds extra fields to an internal request
         SolrDocument doc = (SolrDocument)o;
         for( String fname : doc.getFieldNames() ) {
-          if( !returnFields.contains( fname ) ) {
+          if( !returnFields.wantsField( fname ) ) {
             doc.removeFields( fname );
           }
         }
@@ -106,7 +107,7 @@ public class BinaryResponseWriter implem
       DocList ids = res.docs;
       TransformContext context = new TransformContext();
       context.query = res.query;
-      context.wantsScores = returnFields.getWantsScore() && ids.hasScores();
+      context.wantsScores = returnFields.wantsScore() && ids.hasScores();
       
       int sz = ids.size();
       codec.writeTag(JavaBinCodec.ARR, sz);
@@ -119,7 +120,7 @@ public class BinaryResponseWriter implem
         transformer.setContext( context );
       }
       
-      Set<String> fnames = returnFields.getFieldNames();
+      Set<String> fnames = returnFields.getLuceneFieldNames();
       context.iterator = ids.iterator();
       for (int i = 0; i < sz; i++) {
         int id = context.iterator.nextDoc();
@@ -137,7 +138,7 @@ public class BinaryResponseWriter implem
     
     public void writeResults(ResultContext ctx, JavaBinCodec codec) throws IOException {
       codec.writeTag(JavaBinCodec.SOLRDOCLST);
-      boolean wantsScores = returnFields.getWantsScore() && ctx.docs.hasScores();
+      boolean wantsScores = returnFields.wantsScore() && ctx.docs.hasScores();
       List l = new ArrayList(3);
       l.add((long) ctx.docs.matches());
       l.add((long) ctx.docs.offset());
@@ -157,7 +158,7 @@ public class BinaryResponseWriter implem
       SolrDocument solrDoc = new SolrDocument();
       for (Fieldable f : doc.getFields()) {
         String fieldName = f.name();
-        if( !returnFields.contains(fieldName) ) 
+        if( !returnFields.wantsField(fieldName) ) 
           continue;
         SchemaField sf = schema.getFieldOrNull(fieldName);
         FieldType ft = null;

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/CSVResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/CSVResponseWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/CSVResponseWriter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/CSVResponseWriter.java Fri Mar 25 21:26:33 2011
@@ -34,6 +34,7 @@ import org.apache.solr.schema.SchemaFiel
 import org.apache.solr.schema.StrField;
 import org.apache.solr.search.DocIterator;
 import org.apache.solr.search.DocList;
+import org.apache.solr.search.ReturnFields;
 import org.apache.solr.search.SolrIndexSearcher;
 
 import java.io.CharArrayWriter;
@@ -235,7 +236,7 @@ class CSVWriter extends TextResponseWrit
       // encapsulator will already be disabled if it wasn't specified
     }
 
-    Collection<String> fields = returnFields.getFieldNames();
+    Collection<String> fields = returnFields.getLuceneFieldNames();
     Object responseObj = rsp.getValues().get("response");
     if (fields==null) {
       if (responseObj instanceof SolrDocumentList) {
@@ -248,7 +249,7 @@ class CSVWriter extends TextResponseWrit
         // get the list of fields from the index
         fields = req.getSearcher().getFieldNames();
       }
-      if (returnFields.getWantsScore()) {
+      if (returnFields.wantsScore()) {
         fields.add("score");
       } else {
         fields.remove("score");

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/JSONResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/JSONResponseWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/JSONResponseWriter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/JSONResponseWriter.java Fri Mar 25 21:26:33 2011
@@ -34,6 +34,7 @@ import org.apache.solr.common.util.Named
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.schema.SchemaField;
+import org.apache.solr.search.ReturnFields;
 
 /**
  * @version $Id$
@@ -321,7 +322,7 @@ class JSONWriter extends TextResponseWri
 
     boolean first=true;
     for (String fname : doc.getFieldNames()) {
-      if (!returnFields.contains(fname)) {
+      if (!returnFields.wantsField(fname)) {
         continue;
       }
       

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/PHPSerializedResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/PHPSerializedResponseWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/PHPSerializedResponseWriter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/PHPSerializedResponseWriter.java Fri Mar 25 21:26:33 2011
@@ -31,6 +31,7 @@ import org.apache.solr.common.params.Com
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.schema.SchemaField;
+import org.apache.solr.search.ReturnFields;
 
 
 /**
@@ -113,7 +114,7 @@ class PHPSerializedWriter extends JSONWr
     LinkedHashMap <String,Object> multi = new LinkedHashMap<String, Object>();
 
     for (String fname : doc.getFieldNames()) {
-      if(!returnFields.contains(fname)){
+      if(!returnFields.wantsField(fname)){
         continue;
       }
 

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/SolrQueryResponse.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/SolrQueryResponse.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/SolrQueryResponse.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/SolrQueryResponse.java Fri Mar 25 21:26:33 2011
@@ -19,6 +19,7 @@ package org.apache.solr.response;
 
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.search.ReturnFields;
 
 import java.util.*;
 

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/TextResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/TextResponseWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/TextResponseWriter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/TextResponseWriter.java Fri Mar 25 21:26:33 2011
@@ -33,6 +33,7 @@ import org.apache.solr.response.transfor
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.search.DocList;
+import org.apache.solr.search.ReturnFields;
 
 /** Base class for text-oriented response writers.
  *
@@ -230,7 +231,7 @@ public abstract class TextResponseWriter
     DocList ids = res.docs;
     TransformContext context = new TransformContext();
     context.query = res.query;
-    context.wantsScores = fields.getWantsScore() && ids.hasScores();
+    context.wantsScores = fields.wantsScore() && ids.hasScores();
     writeStartDocumentList(name, ids.offset(), ids.size(), ids.matches(), 
         context.wantsScores ? new Float(ids.maxScore()) : null );
     
@@ -241,7 +242,7 @@ public abstract class TextResponseWriter
       transformer.setContext( context );
     }
     int sz = ids.size();
-    Set<String> fnames = fields.getFieldNames();
+    Set<String> fnames = fields.getLuceneFieldNames();
     for (int i=0; i<sz; i++) {
       int id = context.iterator.nextDoc();
       Document doc = context.searcher.doc(id, fnames);

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/XMLWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/XMLWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/XMLWriter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/XMLWriter.java Fri Mar 25 21:26:33 2011
@@ -33,6 +33,7 @@ import org.apache.solr.common.util.Named
 import org.apache.solr.common.util.XML;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.schema.SchemaField;
+import org.apache.solr.search.ReturnFields;
 
 
 public final class XMLWriter extends TextResponseWriter {
@@ -192,7 +193,7 @@ public final class XMLWriter extends Tex
     incLevel();
 
     for (String fname : doc.getFieldNames()) {
-      if (!returnFields.contains(fname)) {
+      if (!returnFields.wantsField(fname)) {
         continue;
       }
       

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenter.java Fri Mar 25 21:26:33 2011
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
  */
 public class ExplainAugmenter extends TransformerWithContext
 {
-  static enum Style {
+  public static enum Style {
     NL,
     TEXT,
     HTML

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java?rev=1085564&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java Fri Mar 25 21:26:33 2011
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.response.transform;
+
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.util.NamedList;
+
+/**
+ * Return a field with a name that is different that what is indexed
+ *
+ * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
+ * @since solr 4.0
+ */
+public class RenameFieldsTransformer extends DocTransformer
+{
+  final NamedList<String> rename;
+
+  public RenameFieldsTransformer( NamedList<String> rename )
+  {
+    this.rename = rename;
+  }
+
+  @Override
+  public void transform(SolrDocument doc, int docid) {
+    for( int i=0; i<rename.size(); i++ ) {
+      Object v = doc.remove( rename.getName(i) );
+      if( v != null ) {
+        doc.setField(rename.getVal(i), v);
+      }
+    }
+  }
+}

Copied: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java (from r1085451, lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocValuesAugmenter.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java?p2=lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java&p1=lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocValuesAugmenter.java&r1=1085451&r2=1085564&rev=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocValuesAugmenter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java Fri Mar 25 21:26:33 2011
@@ -17,29 +17,35 @@
 package org.apache.solr.response.transform;
 
 import org.apache.solr.common.SolrDocument;
-import org.apache.solr.search.function.DocValues;
+import org.apache.solr.search.QParser;
+import org.apache.solr.search.function.ValueSource;
 
 /**
  * Add values from a ValueSource (function query etc)
+ * 
+ * NOT really sure how or if this could work...
  *
  * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
  * @since solr 4.0
  */
-public class DocValuesAugmenter extends DocTransformer
+public class ValueSourceAugmenter extends DocTransformer
 {
-  final String name;
-  final DocValues values;
+  public final String name;
+  public final QParser qparser;
+  public final ValueSource values;
 
-  public DocValuesAugmenter( String name, DocValues values )
+  public ValueSourceAugmenter( String name, QParser qparser, ValueSource values )
   {
     this.name = name;
+    this.qparser = qparser;
     this.values = values;
   }
 
   @Override
   public void transform(SolrDocument doc, int docid) {
     // TODO, should know what the real type is -- not always string
-    Object v = values.strVal( docid );
+    // how do we get to docvalues?
+    Object v = "now what..."; //values.g.strVal( docid );
     doc.setField( name, v );
   }
 }

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java Fri Mar 25 21:26:33 2011
@@ -582,7 +582,7 @@ public class QueryParsing {
 
     boolean opt(char ch) {
       eatws();
-      if (val.charAt(pos) == ch) {
+      if (pos < end && val.charAt(pos) == ch) {
         pos++;
         return true;
       }
@@ -707,6 +707,28 @@ public class QueryParsing {
       return null;
     }
 
+    public String getGlobbedId(String errMessage) throws ParseException {
+      eatws();
+      int id_start = pos;
+      char ch;
+      if (pos < end && (ch = val.charAt(pos)) != '$' && (Character.isJavaIdentifierStart(ch) || ch=='?' || ch=='*')) {
+        pos++;
+        while (pos < end) {
+          ch = val.charAt(pos);
+          if (!(Character.isJavaIdentifierPart(ch) || ch=='?' || ch=='*') && ch != '.') {
+            break;
+          }
+          pos++;
+        }
+        return val.substring(id_start, pos);
+      }
+
+      if (errMessage != null) {
+        throw new ParseException(errMessage + " at pos " + pos + " str='" + val + "'");
+      }
+      return null;
+    }
+
     /**
      * Skips leading whitespace and returns whatever sequence of non 
      * whitespace it can find (or hte empty string)

Copied: lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java (from r1085451, lucene/dev/trunk/solr/src/java/org/apache/solr/response/ReturnFields.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java?p2=lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java&p1=lucene/dev/trunk/solr/src/java/org/apache/solr/response/ReturnFields.java&r1=1085451&r2=1085564&rev=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/ReturnFields.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java Fri Mar 25 21:26:33 2011
@@ -14,22 +14,34 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.response;
+package org.apache.solr.search;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 
+import org.apache.commons.io.FilenameUtils;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.Query;
+import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.ShardParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.NamedList;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.transform.DocIdAugmenter;
 import org.apache.solr.response.transform.DocTransformer;
 import org.apache.solr.response.transform.DocTransformers;
 import org.apache.solr.response.transform.ExplainAugmenter;
+import org.apache.solr.response.transform.RenameFieldsTransformer;
 import org.apache.solr.response.transform.ScoreAugmenter;
 import org.apache.solr.response.transform.ValueAugmenter;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.apache.solr.util.SolrPluginUtils;
+import org.apache.solr.response.transform.ValueSourceAugmenter;
+import org.apache.solr.search.function.FunctionQuery;
+import org.apache.solr.search.function.QueryValueSource;
+import org.apache.solr.search.function.ValueSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,122 +55,304 @@ public class ReturnFields
 {
   static final Logger log = LoggerFactory.getLogger( ReturnFields.class );
   
+  // Special Field Keys
   public static final String SCORE = "score";
+  // some special syntax for these guys?
+  // Should these have factories... via plugin utils...
   public static final String DOCID = "_docid_";
   public static final String SHARD = "_shard_";
   public static final String EXPLAIN = "_explain_";
 
-  private Set<String> fields; // includes 'augment' names or null
+  private final List<String> globs = new ArrayList<String>(1);
+  private final Set<String> fields = new LinkedHashSet<String>(); // order is important for CSVResponseWriter
+  private Set<String> okFieldNames = new HashSet<String>(); // Collection of everything that could match
+  
   private DocTransformer transformer;
-  private boolean wantsScore = false;
+  private boolean _wantsScore = false;
+  private boolean _wantsAllFields = false;
 
+  public ReturnFields() {
+    _wantsAllFields = true;
+  }
 
-  public static ReturnFields getReturnFields(SolrQueryRequest req)
-  {
-    return getReturnFields( req.getParams().get(CommonParams.FL), req );
+  public ReturnFields(SolrQueryRequest req) {
+    this( req.getParams().get(CommonParams.FL), req );
   }
 
-  public static ReturnFields getReturnFields(String fl, SolrQueryRequest req)
-  {
-    ReturnFields rf = new ReturnFields();
-    rf.wantsScore = false;
-    rf.fields = new LinkedHashSet<String>(); // order is important for CSVResponseWriter
-    boolean allFields = false;
+  public ReturnFields(String fl, SolrQueryRequest req) {
+//    this( (fl==null)?null:SolrPluginUtils.split(fl), req );
+    if( fl == null ) {
+      parseFieldList((String[])null, req);
+    }
+    else {
+      if( fl.trim().length() == 0 ) {
+        // legacy thing to support fl='  ' => fl=*,score!
+        // maybe time to drop support for this?
+        // See ConvertedLegacyTest
+        _wantsScore = true;
+        _wantsAllFields = true;
+        transformer = new ScoreAugmenter(SCORE);
+      }
+      else {
+        parseFieldList( new String[]{fl}, req);
+      }
+    }
+    req.getCore().log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);  // nocommit
+  }
 
+  public ReturnFields(String[] fl, SolrQueryRequest req) {
+    parseFieldList(fl, req);
+    req.getCore().log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);  // nocommit
+  }
+
+  private void parseFieldList(String[] fl, SolrQueryRequest req) {
+    _wantsScore = false;
+    _wantsAllFields = false;
+    if (fl == null || fl.length == 0 || fl.length == 1 && fl[0].length()==0) {
+      _wantsAllFields = true;
+      return;
+    }
+
+    NamedList<String> rename = new NamedList<String>();
     DocTransformers augmenters = new DocTransformers();
-    if (fl != null) {
-      // TODO - this could become more efficient if widely used.
-      String[] flst = SolrPluginUtils.split(fl);
-      if (flst.length > 0 && !(flst.length==1 && flst[0].length()==0)) {
-        IndexSchema schema = req.getSchema();
-        for (String name : flst) {
-          if( "*".equals( name ) ) {
-            allFields = true;
-          }
-          else if( SCORE.equals( name ) ) {
-            rf.fields.add( name );
-            rf.wantsScore = true;
-            augmenters.addTransformer( new ScoreAugmenter( SCORE ) );
-          }
-          else {
-            rf.fields.add( name );
-
-            // Check if it is a real score
-            SchemaField sf = schema.getFieldOrNull( name );
-            if( sf == null ) {
-              // not a field name, but possibly return value
-              if( DOCID.equals( name ) ) {
-                augmenters.addTransformer( new DocIdAugmenter( DOCID ) );
-              }
-              else if( SHARD.equals( name ) ) {
-                String id = "getshardid???";
-                augmenters.addTransformer( new ValueAugmenter( SHARD, id ) );
-              }
-              else if( EXPLAIN.equals( name ) ) {
-                augmenters.addTransformer( new ExplainAugmenter( EXPLAIN ) );
-              }
-              else if( name.startsWith( "{!func}") ) {
-                // help?  not sure how to parse a ValueSorce
-                // -- not to mention, we probably want to reuse existing ones!
-                augmenters.addTransformer( new ValueAugmenter( name, "TODO:"+name ) );
-//                try {
-//                  String func = name.substring( "{!func}".length() );
-//                  SolrParams local = null;
-//                  FunctionQParser p = new FunctionQParser( func, local, req.getParams(), req );
-//                  Query q = p.parse();
-//                  ValueSource vs = p.parseValueSource();
-//                  AtomicReaderContext ctx = new AtomicReaderContext( req.getSearcher().getIndexReader() );
-//                  Map mmm = null; // ?????
-//                  DocValues values = p.parseValueSource().getValues( mmm, ctx );
-//                  augmenters.addAugmenter( new DocValuesAugmenter( name, values ) );
-//                }
-//                catch( Exception ex ) {
-//                  throw new SolrException( org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST,
-//                      "Unable to parse augmented field: "+name, ex );
-//                }
-              }
-              else { 
-                // maybe throw an exception?
-//                throw new SolrException( org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST,
-//                    "Unknown Return Field: "+name );
-              }
-            }
-          }
-        }
+    for (String fieldList : fl) {
+      add(fieldList,rename,augmenters,req);
+    }
+    if( rename.size() > 0 ) {
+      for( int i=0; i<rename.size(); i++ ) {
+        okFieldNames.add( rename.getVal(i) );
       }
+      augmenters.addTransformer( new RenameFieldsTransformer( rename ) );
     }
     
-    // Legacy behavior? "score" == "*,score"
-    if( rf.fields.size() == 1 && rf.wantsScore ) {
-      allFields = true;
+    // Legacy behavior? "score" == "*,score"  Distributed tests for this
+    if( fields.size() == 1 && _wantsScore ) {
+      _wantsAllFields = true;
     }
     
-    if( allFields || rf.fields.isEmpty() ) {
-      rf.fields = null;
+    if( !_wantsAllFields ) {
+      if( !globs.isEmpty() ) {
+        // TODO??? need to fill up the fields with matching field names in the index
+        // and add them to okFieldNames?
+        // maybe just get all fields?
+        // this would disable field selection optimization... i think thatis OK
+        fields.clear(); // this will get all fields, and use wantsField to limit
+      }
+      okFieldNames.addAll( fields );
     }
-    
+        
     if( augmenters.size() == 1 ) {
-      rf.transformer = augmenters.getTransformer(0);
+      transformer = augmenters.getTransformer(0);
     }
     else if( augmenters.size() > 1 ) {
-      rf.transformer = augmenters;
+      transformer = augmenters;
     }
-    return rf;
   }
 
-  public Set<String> getFieldNames()
+  private void add(String fl, NamedList<String> rename, DocTransformers augmenters, SolrQueryRequest req) {
+    if( fl == null ) {
+      return;
+    }
+    try {
+      QueryParsing.StrParser sp = new QueryParsing.StrParser(fl);
+
+      for(;;) {
+        sp.opt(',');
+        sp.eatws();
+        if (sp.pos >= sp.end) break;
+
+        int start = sp.pos;
+
+        // short circuit test for a really simple field name
+        String key = null;
+        String field = sp.getId(null);
+        char ch = sp.ch();
+
+        if (field != null) {
+          if (sp.opt('=')) {
+            // this was a key, not a field name
+            key = field;
+            field = null;
+            sp.eatws();
+            start = sp.pos;
+          } else {
+            if (ch==' ' || ch == ',' || ch==0) {
+              String disp = (key==null) ? field : key; 
+              fields.add( field ); // need to put in the map to maintain order for things like CSVResponseWriter
+              okFieldNames.add( field );
+              okFieldNames.add( key );
+              // a valid field name
+              if(SCORE.equals(field)) {
+                _wantsScore = true;
+                augmenters.addTransformer( new ScoreAugmenter( disp ) );
+              }
+              else if( DOCID.equals( field ) ) {
+                augmenters.addTransformer( new DocIdAugmenter( disp ) );
+              }
+              else if( SHARD.equals( field ) ) {
+                String id = "TODO! getshardid???";
+                augmenters.addTransformer( new ValueAugmenter( disp, id ) );
+              }
+              else if( EXPLAIN.equals( field ) ) {
+                // TODO? pass params to transformers?
+                augmenters.addTransformer( new ExplainAugmenter( disp, ExplainAugmenter.Style.NL ) );
+              }
+              else if( key != null ){
+                rename.add(field, key);
+              }
+              continue;
+            }
+            // an invalid field name... reset the position pointer to retry
+            sp.pos = start;
+            field = null;
+          }
+        }
+
+        if (field == null && sp.pos > start) {
+          // if we are here, we must have read "key = "
+          field = sp.getId(null);
+          ch = sp.ch();
+          if (field != null && (ch==' ' || ch == ',' || ch==0)) {
+            rename.add(field, key);
+            okFieldNames.add( field );
+            okFieldNames.add( key );
+            continue;
+          }
+          // an invalid field name... reset the position pointer to retry
+          sp.pos = start;
+          field = null;
+        }
+
+        if (field == null) {
+          // We didn't find a simple name, so let's see if it's a globbed field name.
+          // Globbing only works with recommended field names.
+
+          field = sp.getGlobbedId(null);
+          ch = sp.ch();
+          if (field != null && (ch==' ' || ch == ',' || ch==0)) {
+            // "*" looks and acts like a glob, but we give it special treatment
+            if ("*".equals(field)) {
+              _wantsAllFields = true;
+            } else {
+              globs.add(field);
+            }
+            continue;
+          }
+
+          // an invalid glob
+          sp.pos = start;
+        }
+
+        // let's try it as a function instead
+        String funcStr = sp.val.substring(start);
+
+        QParser parser = QParser.getParser(funcStr, FunctionQParserPlugin.NAME, req);
+        Query q = null;
+        ValueSource vs = null;
+
+        try {
+          if (parser instanceof FunctionQParser) {
+            FunctionQParser fparser = (FunctionQParser)parser;
+            fparser.setParseMultipleSources(false);
+            fparser.setParseToEnd(false);
+
+            q = fparser.getQuery();
+
+            if (fparser.localParams != null) {
+              if (fparser.valFollowedParams) {
+                // need to find the end of the function query via the string parser
+                int leftOver = fparser.sp.end - fparser.sp.pos;
+                sp.pos = sp.end - leftOver;   // reset our parser to the same amount of leftover
+              } else {
+                // the value was via the "v" param in localParams, so we need to find
+                // the end of the local params themselves to pick up where we left off
+                sp.pos = start + fparser.localParamsEnd;
+              }
+            } else {
+              // need to find the end of the function query via the string parser
+              int leftOver = fparser.sp.end - fparser.sp.pos;
+              sp.pos = sp.end - leftOver;   // reset our parser to the same amount of leftover
+            }
+          } else {
+            // A QParser that's not for function queries.
+            // It must have been specified via local params.
+            q = parser.getQuery();
+
+            assert parser.getLocalParams() != null;
+            sp.pos = start + parser.localParamsEnd;
+          }
+
+
+          if (q instanceof FunctionQuery) {
+            vs = ((FunctionQuery)q).getValueSource();
+          } else {
+            vs = new QueryValueSource(q, 0.0f);
+          }
+
+          if (key==null) {
+            SolrParams localParams = parser.getLocalParams();
+            if (localParams != null) {
+              key = localParams.get("key");
+            }
+            if (key == null) {
+              // use the function name itself as the field name
+              key = sp.val.substring(start, sp.pos);
+            }
+          }
+          
+          augmenters.addTransformer( new ValueSourceAugmenter( key, parser, vs ) );
+        }
+        catch (ParseException e) {
+          // try again, simple rules for a field name with no whitespace
+          sp.pos = start;
+          field = sp.getSimpleString();
+
+          if (req.getSchema().getFieldOrNull(field) != null) {
+            // OK, it was an oddly named field
+            fields.add(field);
+            if( key != null ) {
+              rename.add(field, key);
+            }
+          } else {
+            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing fieldname: " + e.getMessage(), e);
+          }
+        }
+
+       // end try as function
+
+      } // end for(;;)
+    } catch (ParseException e) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing fieldname", e);
+    }
+  }
+  
+  public Set<String> getLuceneFieldNames()
   {
-    return fields;
+    return (_wantsAllFields || fields.isEmpty()) ? null : fields;
   }
 
-  public boolean getWantsScore()
+  public boolean wantsAllFields()
+  {
+    return _wantsAllFields;
+  }
+  
+  public boolean wantsScore()
   {
-    return wantsScore;
+    return _wantsScore;
   }
 
-  public boolean contains( String name )
+  public boolean wantsField( String name )
   {
-    return fields==null || fields.contains( name );
+    if( _wantsAllFields || okFieldNames.contains( name ) ){
+      return true;
+    }
+    for( String s : globs ) {
+      // TODO something better?
+      if( FilenameUtils.wildcardMatch( name, s ) ) {
+        return true;
+      }
+    }
+    return false;
   }
 
   public DocTransformer getTransformer()

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/util/SolrPluginUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/util/SolrPluginUtils.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/util/SolrPluginUtils.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/util/SolrPluginUtils.java Fri Mar 25 21:26:33 2011
@@ -37,7 +37,6 @@ import org.apache.solr.handler.component
 import org.apache.solr.handler.component.ResponseBuilder;
 import org.apache.solr.highlight.SolrHighlighter;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.response.ReturnFields;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
@@ -147,8 +146,8 @@ public class SolrPluginUtils {
     }
 
     ReturnFields returnFields = res.getReturnFields();
-    if(returnFields.getFieldNames() != null) {
-      Set<String> fieldFilter = returnFields.getFieldNames();
+    if(returnFields.getLuceneFieldNames() != null) {
+      Set<String> fieldFilter = returnFields.getLuceneFieldNames();
 
       if (rb.doHighlights) {
         // copy return fields list

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java Fri Mar 25 21:26:33 2011
@@ -22,6 +22,7 @@ import org.apache.solr.common.SolrDocume
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.util.DateUtil;
 import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.search.ReturnFields;
 import org.junit.*;
 
 import java.io.StringWriter;
@@ -128,19 +129,19 @@ public class TestCSVResponseWriter exten
     rsp.add("response", sdl);
     QueryResponseWriter w = new CSVResponseWriter();
     
-    rsp.setReturnFields( ReturnFields.getReturnFields("id,foo_s", req) );
+    rsp.setReturnFields( new ReturnFields("id,foo_s", req) );
     StringWriter buf = new StringWriter();
     w.write(buf, req, rsp);
     assertEquals("id,foo_s\n1,hi\n2,\n", buf.toString());
 
     // try scores
-    rsp.setReturnFields( ReturnFields.getReturnFields("id,score,foo_s", req) );
+    rsp.setReturnFields( new ReturnFields("id,score,foo_s", req) );
     buf = new StringWriter();
     w.write(buf, req, rsp);
     assertEquals("id,score,foo_s\n1,2.718,hi\n2,89.83,\n", buf.toString());
 
     // get field values from docs... should be ordered and not include score unless requested
-    rsp.setReturnFields( ReturnFields.getReturnFields("*", req) );
+    rsp.setReturnFields( new ReturnFields("*", req) );
     buf = new StringWriter();
     w.write(buf, req, rsp);
     assertEquals("id,foo_i,foo_s,foo_l,foo_b,foo_f,foo_d,foo_dt,v_ss,v2_ss\n" +
@@ -150,7 +151,7 @@ public class TestCSVResponseWriter exten
     
 
     // get field values and scores - just check that the scores are there... we don't guarantee where
-    rsp.setReturnFields( ReturnFields.getReturnFields("*,score", req) );
+    rsp.setReturnFields( new ReturnFields("*,score", req) );
     buf = new StringWriter();
     w.write(buf, req, rsp);
     String s = buf.toString();

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java?rev=1085564&r1=1085563&r2=1085564&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java Fri Mar 25 21:26:33 2011
@@ -17,6 +17,8 @@
 package org.apache.solr.search;
 
 import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.response.transform.ExplainAugmenter;
+import org.apache.solr.response.transform.ScoreAugmenter;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -49,4 +51,40 @@ public class TestSolrQueryParser extends
     );
   }
 
+  @Test
+  public void testReturnFields() {
+    ReturnFields rf = new ReturnFields( req("fl", "id,score") );
+    assertTrue( rf.wantsScore() );
+    assertTrue( rf.wantsField( "score" ) );
+    assertTrue( rf.wantsField( "id" ) );
+    assertFalse( rf.wantsField( "xxx" ) );
+    assertTrue( rf.getTransformer() instanceof ScoreAugmenter );
+    
+    rf = new ReturnFields( req("fl", "*") );
+    assertFalse( rf.wantsScore() );
+    assertTrue( rf.wantsField( "xxx" ) );
+    assertTrue( rf.wantsAllFields() );
+    assertNull( rf.getTransformer() );
+    
+    rf = new ReturnFields( req("fl", "_explain_") );
+    assertFalse( rf.wantsScore() );
+    assertFalse( rf.wantsField( "id" ) );
+    assertTrue( rf.getTransformer() instanceof ExplainAugmenter );
+
+    // Check that we want wildcards
+    rf = new ReturnFields( req("fl", "id,aaa*,*bbb") );
+    assertTrue( rf.wantsField( "id" ) );
+    assertTrue( rf.wantsField( "aaaa" ) );
+    assertTrue( rf.wantsField( "xxxbbb" ) );
+    assertFalse( rf.wantsField( "aa" ) );
+    assertFalse( rf.wantsField( "bb" ) );
+
+    
+    // From ConvertedLegacyTest, maybe we drop support?
+    rf = new ReturnFields( req("fl", "  ") );
+    assertTrue( rf.wantsScore() );
+    assertTrue( rf.wantsField( "xxx" ) );
+    assertTrue( rf.wantsAllFields() );
+    assertTrue( rf.getTransformer() instanceof ScoreAugmenter );
+  }
 }