You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jb...@apache.org on 2019/07/30 15:07:28 UTC

[lucene-solr] branch master updated (d1706b3 -> 254a17b)

This is an automated email from the ASF dual-hosted git repository.

jbernste pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git.


    from d1706b3  LUCENE-8920: Fix bug preventing FST duplicate tails from being shared when encoded as array-with-gaps
     new d067486  SOLR-13625: Add CsvStream, TsvStream Streaming Expressions and supporting Stream Evaluators
     new 62955b1  SOLR-13625: Fix broken test cases
     new 254a17b  SOLR-13625: Fix precommit

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/solr/client/solrj/io/Lang.java |   8 +-
 .../{AppendEvaluator.java => ConcatEvaluator.java} |  52 +++++----
 .../{NormEvaluator.java => DateEvaluator.java}     |  57 +++++----
 .../{Log10Evaluator.java => DoubleEvaluator.java}  |   6 +-
 .../{SineEvaluator.java => LongEvaluator.java}     |  10 +-
 .../client/solrj/io/eval/RecursiveEvaluator.java   |  21 ++++
 .../solrj/io/eval/RecursiveNumericEvaluator.java   |  11 +-
 .../io/eval/RecursiveNumericListEvaluator.java     |   2 +
 .../solrj/io/eval/SetColumnLabelsEvaluator.java    |  12 +-
 .../solrj/io/eval/SetRowLabelsEvaluator.java       |  14 ++-
 .../solr/client/solrj/io/eval/UuidEvaluator.java   |   2 +-
 .../stream/{HavingStream.java => CsvStream.java}   | 130 ++++++++++-----------
 .../solr/client/solrj/io/stream/SolrStream.java    |  12 ++
 .../{CalculatorStream.java => TsvStream.java}      |  77 ++++--------
 .../org/apache/solr/client/solrj/io/TestLang.java  |   2 +-
 .../client/solrj/io/stream/MathExpressionTest.java | 117 +++++++++++++++++++
 .../solrj/io/stream/StreamDecoratorTest.java       |  67 +++++++++++
 .../io/stream/eval/AbsoluteValueEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/AddEvaluatorTest.java     |   7 +-
 .../io/stream/eval/ArcCosineEvaluatorTest.java     |   4 +-
 .../solrj/io/stream/eval/ArcSineEvaluatorTest.java |   4 +-
 .../io/stream/eval/ArcTangentEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/CeilingEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/CosineEvaluatorTest.java  |   4 +-
 .../io/stream/eval/CubedRootEvaluatorTest.java     |   4 +-
 .../solrj/io/stream/eval/DivideEvaluatorTest.java  |  10 +-
 .../solrj/io/stream/eval/FloorEvaluatorTest.java   |   4 +-
 .../stream/eval/HyperbolicCosineEvaluatorTest.java |   4 +-
 .../stream/eval/HyperbolicSineEvaluatorTest.java   |   4 +-
 .../eval/HyperbolicTangentEvaluatorTest.java       |   4 +-
 .../solrj/io/stream/eval/ModuloEvaluatorTest.java  |  10 +-
 .../io/stream/eval/MultiplyEvaluatorTest.java      |   7 +-
 .../io/stream/eval/NaturalLogEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/PowerEvaluatorTest.java   |   2 +-
 .../solrj/io/stream/eval/RoundEvaluatorTest.java   |   4 +-
 .../solrj/io/stream/eval/SineEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SquareRootEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SubtractEvaluatorTest.java      |   6 +-
 .../solrj/io/stream/eval/TangentEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/UuidEvaluatorTest.java    |  13 ++-
 40 files changed, 481 insertions(+), 238 deletions(-)
 copy solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/{AppendEvaluator.java => ConcatEvaluator.java} (54%)
 copy solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/{NormEvaluator.java => DateEvaluator.java} (50%)
 copy solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/{Log10Evaluator.java => DoubleEvaluator.java} (88%)
 copy solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/{SineEvaluator.java => LongEvaluator.java} (88%)
 copy solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/{HavingStream.java => CsvStream.java} (57%)
 copy solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/{CalculatorStream.java => TsvStream.java} (63%)


[lucene-solr] 03/03: SOLR-13625: Fix precommit

Posted by jb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jbernste pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 254a17b3b0df118a1317759c0be0ad20d489283e
Author: Joel Bernstein <jb...@apache.org>
AuthorDate: Tue Jul 30 10:41:50 2019 -0400

    SOLR-13625: Fix precommit
---
 solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java          | 1 -
 .../src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java     | 3 ---
 .../org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java  | 1 -
 .../apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java | 1 -
 .../org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java | 1 -
 5 files changed, 7 deletions(-)

diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
index a83afd7..3ace1f7 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
@@ -19,7 +19,6 @@ package org.apache.solr.client.solrj.io;
 import org.apache.solr.client.solrj.io.eval.*;
 import org.apache.solr.client.solrj.io.graph.GatherNodesStream;
 import org.apache.solr.client.solrj.io.graph.ShortestPathStream;
-import org.apache.solr.client.solrj.io.ops.ConcatOperation;
 import org.apache.solr.client.solrj.io.ops.DistinctOperation;
 import org.apache.solr.client.solrj.io.ops.GroupOperation;
 import org.apache.solr.client.solrj.io.ops.ReplaceOperation;
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java
index 7b5d0d8..a1f8d8e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java
@@ -75,9 +75,6 @@ public class TsvStream extends CsvStream implements Expressible {
 
   protected String[] split(String line) {
     String[] parts = line.split("\\t", -1);
-    for(String s : parts) {
-      System.out.println("part:"+s+":"+line.length()+":"+line+":");
-    }
     return parts;
   }
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java
index 0e431d8..87a12bf 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.solr.client.solrj.io.stream.eval;
 
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java
index 1bc3ccc..b025ce9 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.solr.client.solrj.io.stream.eval;
 
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java
index 5b434e6..ee40e65 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java
@@ -18,7 +18,6 @@ package org.apache.solr.client.solrj.io.stream.eval;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.UUID;
 
 import org.apache.solr.SolrTestCase;
 import org.apache.solr.client.solrj.io.Tuple;


[lucene-solr] 02/03: SOLR-13625: Fix broken test cases

Posted by jb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jbernste pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 62955b1a4e98c4a583f9c6c5d71adc7947423b90
Author: Joel Bernstein <jb...@apache.org>
AuthorDate: Tue Jul 30 10:01:15 2019 -0400

    SOLR-13625: Fix broken test cases
---
 .../java/org/apache/solr/client/solrj/io/Lang.java |   2 +-
 .../solr/client/solrj/io/eval/ConcatEvaluator.java |  63 +++++++++++
 .../client/solrj/io/eval/RecursiveEvaluator.java   |  21 ++++
 .../solrj/io/eval/RecursiveNumericEvaluator.java   |  11 +-
 .../io/eval/RecursiveNumericListEvaluator.java     |   2 +
 .../solrj/io/eval/SetColumnLabelsEvaluator.java    |  12 ++-
 .../solrj/io/eval/SetRowLabelsEvaluator.java       |  14 ++-
 .../solr/client/solrj/io/eval/UuidEvaluator.java   |   2 +-
 .../solr/client/solrj/io/stream/CsvStream.java     |   3 +-
 .../solr/client/solrj/io/stream/SolrStream.java    |  12 +++
 .../client/solrj/io/stream/MathExpressionTest.java | 117 +++++++++++++++++++++
 .../solrj/io/stream/StreamDecoratorTest.java       | 102 ------------------
 .../io/stream/eval/AbsoluteValueEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/AddEvaluatorTest.java     |   6 +-
 .../io/stream/eval/ArcCosineEvaluatorTest.java     |   4 +-
 .../solrj/io/stream/eval/ArcSineEvaluatorTest.java |   4 +-
 .../io/stream/eval/ArcTangentEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/CeilingEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/CosineEvaluatorTest.java  |   4 +-
 .../io/stream/eval/CubedRootEvaluatorTest.java     |   4 +-
 .../solrj/io/stream/eval/DivideEvaluatorTest.java  |  10 +-
 .../solrj/io/stream/eval/FloorEvaluatorTest.java   |   4 +-
 .../stream/eval/HyperbolicCosineEvaluatorTest.java |   4 +-
 .../stream/eval/HyperbolicSineEvaluatorTest.java   |   4 +-
 .../eval/HyperbolicTangentEvaluatorTest.java       |   4 +-
 .../solrj/io/stream/eval/ModuloEvaluatorTest.java  |  10 +-
 .../io/stream/eval/MultiplyEvaluatorTest.java      |   6 +-
 .../io/stream/eval/NaturalLogEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/PowerEvaluatorTest.java   |   2 +-
 .../solrj/io/stream/eval/RoundEvaluatorTest.java   |   4 +-
 .../solrj/io/stream/eval/SineEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SquareRootEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SubtractEvaluatorTest.java      |   6 +-
 .../solrj/io/stream/eval/TangentEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/UuidEvaluatorTest.java    |  12 ++-
 35 files changed, 310 insertions(+), 167 deletions(-)

diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
index 60ce437..a83afd7 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
@@ -107,7 +107,6 @@ public class Lang {
 
             // tuple manipulation operations
         .withFunctionName("replace", ReplaceOperation.class)
-        .withFunctionName("concat", ConcatOperation.class)
 
             // stream reduction operations
         .withFunctionName("group", GroupOperation.class)
@@ -297,6 +296,7 @@ public class Lang {
         .withFunctionName("double", DoubleEvaluator.class)
         .withFunctionName("long", LongEvaluator.class)
         .withFunctionName("dateTime", DateEvaluator.class)
+        .withFunctionName("concat", ConcatEvaluator.class)
 
         // Boolean Stream Evaluators
 
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConcatEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConcatEvaluator.java
new file mode 100644
index 0000000..124faf5
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConcatEvaluator.java
@@ -0,0 +1,63 @@
+/*
+ * 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.client.solrj.io.eval;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class ConcatEvaluator extends RecursiveObjectEvaluator implements ManyValueWorker {
+  protected static final long serialVersionUID = 1L;
+  private String delim = "";
+
+  public ConcatEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+    super(expression, factory);
+
+    List<StreamExpressionNamedParameter> namedParams = factory.getNamedOperands(expression);
+
+    for(StreamExpressionNamedParameter namedParam : namedParams){
+      if(namedParam.getName().equals("delim")){
+        this.delim = namedParam.getParameter().toString().trim();
+      } else {
+        throw new IOException("Unexpected named parameter:"+namedParam.getName());
+      }
+    }
+
+  }
+
+  @Override
+  public Object doWork(Object values[]) throws IOException {
+
+    StringBuilder buff = new StringBuilder();
+
+    for(Object o : values) {
+        if(buff.length() > 0) {
+          buff.append(delim);
+        }
+        String s = o.toString();
+        if(s.startsWith("\"") && s.endsWith("\"")) {
+          s = s.substring(1, s.length()-1);
+        }
+        buff.append(s.toString());
+    }
+
+    return buff.toString();
+  }
+}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java
index 0278839..a5fae7e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java
@@ -73,6 +73,27 @@ public abstract class RecursiveEvaluator implements StreamEvaluator, ValueWorker
       return new BigDecimal(value.toString());
     }
     else if(value instanceof Collection){
+      //Let's first check to see if we have a List of Strings.
+      //If we do let's try and convert to a list of doubles and see what happens
+      try {
+        List<Number> vector = new ArrayList();
+        boolean allDoubles = true;
+        for(Object o : (Collection)value) {
+          if(o instanceof String) {
+            Double d = Double.parseDouble(o.toString());
+            vector.add(d);
+          } else {
+            allDoubles = false;
+            break;
+          }
+        }
+        if(allDoubles) {
+          return vector;
+        }
+      } catch(Exception e) {
+
+      }
+
       return ((Collection<?>)value).stream().map(innerValue -> normalizeInputType(innerValue)).collect(Collectors.toList());
     }
     else if(value.getClass().isArray()){
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java
index 948f003..b589f6e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -46,12 +47,20 @@ public abstract class RecursiveNumericEvaluator extends RecursiveEvaluator {
     }
     else if(value instanceof BigDecimal){
       return value;
+    } else if(value instanceof String) {
+      return new BigDecimal((String)value);
     }
     else if(value instanceof Number){
       return new BigDecimal(value.toString());
     }
     else if(value instanceof Collection){
-      return ((Collection<?>)value).stream().map(innerValue -> normalizeInputType(innerValue)).collect(Collectors.toList());
+      if(value instanceof List) {
+        if(((List)value).get(0) instanceof Number) {
+          return  value;
+        }
+      }
+
+      return ((Collection<?>) value).stream().map(innerValue -> normalizeInputType(innerValue)).collect(Collectors.toList());
     }
     else if(value.getClass().isArray()){
       Stream<?> stream = Stream.empty();
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericListEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericListEvaluator.java
index 08305b1..e6dce63 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericListEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericListEvaluator.java
@@ -52,6 +52,8 @@ public abstract class RecursiveNumericListEvaluator extends RecursiveEvaluator {
         return null;
       }
       return new BigDecimal(value.toString());
+    } else if (value instanceof String) {
+      return new BigDecimal(value.toString());
     }
     else if(value instanceof BigDecimal){
       return (BigDecimal)value;
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetColumnLabelsEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetColumnLabelsEvaluator.java
index 1d589af..a178c2e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetColumnLabelsEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetColumnLabelsEvaluator.java
@@ -18,6 +18,7 @@
 package org.apache.solr.client.solrj.io.eval;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Locale;
 import java.util.List;
 
@@ -39,8 +40,15 @@ public class SetColumnLabelsEvaluator extends RecursiveObjectEvaluator implement
       throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for value, expecting an array of labels.",toExpression(constructingFactory), value2.getClass().getSimpleName()));
     } else {
       Matrix matrix = (Matrix)value1;
-      List<String> colLabels =  (List<String>)value2;
-      matrix.setColumnLabels(colLabels);
+
+      List colLabels =  (List)value2;
+      //Convert numeric labels to strings.
+      List<String> strLabels = new ArrayList(colLabels.size());
+      for(Object o : colLabels) {
+        strLabels.add(o.toString());
+      }
+
+      matrix.setColumnLabels(strLabels);
       return matrix;
     }
   }
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetRowLabelsEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetRowLabelsEvaluator.java
index 66a59c8..390299e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetRowLabelsEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SetRowLabelsEvaluator.java
@@ -18,6 +18,7 @@
 package org.apache.solr.client.solrj.io.eval;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Locale;
 import java.util.List;
 
@@ -39,8 +40,17 @@ public class SetRowLabelsEvaluator extends RecursiveObjectEvaluator implements T
       throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for value, expecting an array of labels.",toExpression(constructingFactory), value2.getClass().getSimpleName()));
     } else {
       Matrix matrix = (Matrix)value1;
-      List<String> rowlabels =  (List<String>)value2;
-      matrix.setRowLabels(rowlabels);
+      List rowlabels =  (List)value2;
+
+      //Convert numeric labels to strings.
+
+      List<String> strLabels = new ArrayList(rowlabels.size());
+
+      for(Object o : rowlabels) {
+        strLabels.add(o.toString());
+      }
+
+      matrix.setRowLabels(strLabels);
       return matrix;
     }
   }
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/UuidEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/UuidEvaluator.java
index ee0f9eb..a7115a9 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/UuidEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/UuidEvaluator.java
@@ -35,7 +35,7 @@ public class UuidEvaluator extends SourceEvaluator {
   
   @Override
   public Object evaluate(Tuple tuple) throws IOException {
-    return UUID.randomUUID();
+    return UUID.randomUUID().toString();
   }
   
   @Override
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CsvStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CsvStream.java
index b8c479e..15ab684 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CsvStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CsvStream.java
@@ -131,6 +131,7 @@ public class CsvStream extends TupleStream implements Expressible {
           throw new IOException("Headers and lines must have the same number of fields [file:"+file+" line number:"+lineNumber+"]");
         }
         Tuple out = new Tuple(new HashMap());
+        out.put("id", file+"_"+lineNumber);
         for(int i=0; i<headers.length; i++) {
           if(fields[i] != null && fields[i].length() > 0) {
             out.put(headers[i], fields[i]);
@@ -147,7 +148,7 @@ public class CsvStream extends TupleStream implements Expressible {
   }
 
   protected String[] split(String line) {
-    String[] fields = line.split(",(?=([^\"]|\"[^\"]*\")*$)",-1);
+    String[] fields = line.split(",(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)",-1);
     for(int i=0; i<fields.length; i++) {
       String f = fields[i];
       if(f.startsWith("\"") && f.endsWith("\"")) {
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
index f9562c2..fad08d2 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
@@ -67,6 +67,8 @@ public class SolrStream extends TupleStream {
   private long checkpoint = -1;
   private CloseableHttpResponse closeableHttpResponse;
   private boolean distrib = true;
+  private String user;
+  private String password;
 
   /**
    * @param baseUrl Base URL of the stream.
@@ -97,6 +99,11 @@ public class SolrStream extends TupleStream {
     this.cache = context.getSolrClientCache();
   }
 
+  public void setCredentials(String user, String password) {
+    this.user = user;
+    this.password = password;
+  }
+
   /**
   * Opens the stream to a single Solr instance.
   **/
@@ -275,6 +282,11 @@ public class SolrStream extends TupleStream {
     query.setPath(p);
     query.setResponseParser(new InputStreamResponseParser(wt));
     query.setMethod(SolrRequest.METHOD.POST);
+
+    if(user != null && password != null) {
+      query.setBasicAuthCredentials(user, password);
+    }
+
     NamedList<Object> genericResponse = server.request(query);
     InputStream stream = (InputStream) genericResponse.get("stream");
     this.closeableHttpResponse = (CloseableHttpResponse)genericResponse.get("closeableResponse");
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java
index bf60f81..25a07de 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java
@@ -210,6 +210,26 @@ public class MathExpressionTest extends SolrCloudTestCase {
   }
 
   @Test
+  public void testConcat() throws Exception {
+    String expr = " select(list(tuple(field1=\"a\", field2=\"b\"), tuple(field1=\"c\", field2=\"d\")), concat(field1, field2, \"hello\", delim=\"-\") as field3)";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    assertEquals(tuples.size(),  2);
+    String s1= tuples.get(0).getString("field3");
+    assertEquals(s1, "a-b-hello");
+    String s2= tuples.get(1).getString("field3");
+    assertEquals(s2, "c-d-hello");
+  }
+
+  @Test
   public void testMemset() throws Exception {
     String expr = "let(echo=\"b, c\"," +
         "              a=memset(list(tuple(field1=val(1), field2=val(10)), tuple(field1=val(2), field2=val(20))), " +
@@ -4462,6 +4482,103 @@ public class MathExpressionTest extends SolrCloudTestCase {
   }
 
   @Test
+  public void testDateTime() throws Exception {
+    String expr = "select(list(tuple(a=20001011:10:11:01), tuple(a=20071011:14:30:20)), dateTime(a, yyyyMMdd:kk:mm:ss) as date)";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    String date = (String)tuples.get(0).get("date");
+    assertEquals(date, "2000-10-11T10:11:01Z");
+    date = (String)tuples.get(1).get("date");
+    assertEquals(date, "2007-10-11T14:30:20Z");
+  }
+
+  @Test
+  public void testDateTimeTZ() throws Exception {
+    String expr = "select(list(tuple(a=20001011), tuple(a=20071011)), dateTime(a, yyyyMMdd, UTC) as date, dateTime(a, yyyyMMdd, EST) as date1, dateTime(a, yyyyMMdd) as date2)";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    String date = (String)tuples.get(0).get("date");
+    String date1 = (String)tuples.get(0).get("date1");
+    String date2 = (String)tuples.get(0).get("date2");
+
+    assertEquals(date, "2000-10-11T00:00:00Z");
+    assertEquals(date1, "2000-10-11T05:00:00Z");
+    assertEquals(date2, "2000-10-11T00:00:00Z");
+
+
+    date = (String)tuples.get(1).get("date");
+    date1 = (String)tuples.get(1).get("date1");
+    date2 = (String)tuples.get(1).get("date2");
+
+    assertEquals(date, "2007-10-11T00:00:00Z");
+    assertEquals(date1, "2007-10-11T05:00:00Z");
+    assertEquals(date2, "2007-10-11T00:00:00Z");
+  }
+
+
+
+  @Test
+  public void testDoubleLong() throws Exception {
+    String expr = "select(tuple(d=\"1.1\", l=\"5000\"), double(d) as d, long(l) as l)";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    assertEquals(tuples.size(),  1);
+    assertTrue(tuples.get(0).get("d") instanceof Double);
+    assertTrue(tuples.get(0).get("l") instanceof Long);
+
+    assertEquals(tuples.get(0).getDouble("d"), 1.1D, 0);
+    assertEquals(tuples.get(0).getLong("l").longValue(), 5000L);
+
+  }
+
+
+  public void testDoubleArray() throws Exception {
+    String expr = "let(a=list(tuple(d=\"1.1\", l=\"5000\"), tuple(d=\"1.3\", l=\"7000\"))," +
+        "              b=col(a, d)," +
+        "              tuple(doubles=double(b)))";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    assertEquals(tuples.size(),  1);
+
+    List<Double> doubles = (List<Double>)tuples.get(0).get("doubles");
+    assertEquals(doubles.get(0), 1.1, 0);
+    assertEquals(doubles.get(1), 1.3, 0);
+
+  }
+
+  @Test
   public void testGaussfit() throws Exception {
     String cexpr = "let(echo=true, " +
         "x=array(79.56,81.32,82.82,84.64,86.18,87.89,89.53,91.14,92.8,94.43,96.08,97.72,99.37,101,102.66,104.3,105.94,107.59,109.23,110.87,112.52,114.13,115.82,117.44,119.27), " +
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
index 65815e1..75474a4 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
@@ -3217,108 +3217,6 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
   }
 
 
-  @Test
-  public void testDateTime() throws Exception {
-    String expr = "select(list(tuple(a=20001011:10:11:01), tuple(a=20071011:14:30:20)), dateTime(a, yyyyMMdd:kk:mm:ss) as date)";
-    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
-    paramsLoc.set("expr", expr);
-    paramsLoc.set("qt", "/stream");
-
-    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
-    TupleStream solrStream = new SolrStream(url, paramsLoc);
-
-    StreamContext context = new StreamContext();
-    solrStream.setStreamContext(context);
-    List<Tuple> tuples = getTuples(solrStream);
-    String date = (String)tuples.get(0).get("date");
-    assertEquals(date, "2000-10-11T10:11:01Z");
-    date = (String)tuples.get(1).get("date");
-    assertEquals(date, "2007-10-11T14:30:20Z");
-  }
-
-  @Test
-  public void testDateTimeTZ() throws Exception {
-    String expr = "select(list(tuple(a=20001011), tuple(a=20071011)), dateTime(a, yyyyMMdd, UTC) as date, dateTime(a, yyyyMMdd, EST) as date1, dateTime(a, yyyyMMdd) as date2)";
-    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
-    paramsLoc.set("expr", expr);
-    paramsLoc.set("qt", "/stream");
-
-    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
-    TupleStream solrStream = new SolrStream(url, paramsLoc);
-
-    StreamContext context = new StreamContext();
-    solrStream.setStreamContext(context);
-    List<Tuple> tuples = getTuples(solrStream);
-    String date = (String)tuples.get(0).get("date");
-    String date1 = (String)tuples.get(0).get("date1");
-    String date2 = (String)tuples.get(0).get("date2");
-
-    assertEquals(date, "2000-10-11T00:00:00Z");
-    assertEquals(date1, "2000-10-11T05:00:00Z");
-    assertEquals(date2, "2000-10-11T00:00:00Z");
-
-
-    date = (String)tuples.get(1).get("date");
-    date1 = (String)tuples.get(1).get("date1");
-    date2 = (String)tuples.get(1).get("date2");
-
-    assertEquals(date, "2007-10-11T00:00:00Z");
-    assertEquals(date1, "2007-10-11T05:00:00Z");
-    assertEquals(date2, "2007-10-11T00:00:00Z");
-  }
-
-
-
-  @Test
-  public void testDoubleLong() throws Exception {
-    String expr = "select(tuple(d=\"1.1\", l=\"5000\"), double(d) as d, long(l) as l)";
-    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
-    paramsLoc.set("expr", expr);
-    paramsLoc.set("qt", "/stream");
-
-    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
-    TupleStream solrStream = new SolrStream(url, paramsLoc);
-
-    StreamContext context = new StreamContext();
-    solrStream.setStreamContext(context);
-    List<Tuple> tuples = getTuples(solrStream);
-    assertEquals(tuples.size(),  1);
-    assertTrue(tuples.get(0).get("d") instanceof Double);
-    assertTrue(tuples.get(0).get("l") instanceof Long);
-
-    assertEquals(tuples.get(0).getDouble("d"), 1.1D, 0);
-    assertEquals(tuples.get(0).getLong("l").longValue(), 5000L);
-
-  }
-
-
-  public void testDoubleLongArray() throws Exception {
-    String expr = "let(a=list(tuple(d=\"1.1\", l=\"5000\"), tuple(d=\"1.3\", l=\"7000\"))," +
-        "              b=col(a, d)," +
-        "              c=col(a, l)," +
-        "              tuple(doubles=double(b)," +
-        "                    longs=long(c)))";
-    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
-    paramsLoc.set("expr", expr);
-    paramsLoc.set("qt", "/stream");
-
-    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
-    TupleStream solrStream = new SolrStream(url, paramsLoc);
-
-    StreamContext context = new StreamContext();
-    solrStream.setStreamContext(context);
-    List<Tuple> tuples = getTuples(solrStream);
-    assertEquals(tuples.size(),  1);
-
-    List<Double> doubles = (List<Double>)tuples.get(0).get("doubles");
-    List<Long> longs = (List<Long>)tuples.get(0).get("longs");
-    assertEquals(doubles.get(0), 1.1, 0);
-    assertEquals(doubles.get(1), 1.3, 0);
-
-    assertEquals(longs.get(0).longValue(), 5000L);
-    assertEquals(longs.get(1).longValue(), 7000L);
-  }
-
 
   @Test
   public void testCommitStream() throws Exception {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AbsoluteValueEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AbsoluteValueEvaluatorTest.java
index f98ac71..75cde6e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AbsoluteValueEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AbsoluteValueEvaluatorTest.java
@@ -107,7 +107,7 @@ public class AbsoluteValueEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("abs(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void absNoValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("abs(a)");
     
@@ -116,7 +116,7 @@ public class AbsoluteValueEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void absNullValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("abs(a)");
     
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java
index 3b85953..0e431d8 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/AddEvaluatorTest.java
@@ -69,7 +69,7 @@ public class AddEvaluatorTest extends SolrTestCase {
     Assert.assertEquals(3.2D, result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void addTwoFieldWithNulls() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("add(a,b)");
     Object result;
@@ -79,7 +79,7 @@ public class AddEvaluatorTest extends SolrTestCase {
     Assert.assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void addTwoFieldsWithNull() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("add(a,b)");
     Object result;
@@ -103,7 +103,7 @@ public class AddEvaluatorTest extends SolrTestCase {
     Assert.assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void addTwoFieldsWithMissingField() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("add(a,b)");
     Object result;
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcCosineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcCosineEvaluatorTest.java
index a0fb968..850ab3d 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcCosineEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcCosineEvaluatorTest.java
@@ -76,7 +76,7 @@ public class ArcCosineEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("acos(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("acos(a)");
     
@@ -84,7 +84,7 @@ public class ArcCosineEvaluatorTest extends SolrTestCase {
     Object result = evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcSineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcSineEvaluatorTest.java
index 23808f2..b754159 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcSineEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcSineEvaluatorTest.java
@@ -76,7 +76,7 @@ public class ArcSineEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("asin(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("asin(a)");
     
@@ -85,7 +85,7 @@ public class ArcSineEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcTangentEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcTangentEvaluatorTest.java
index 07c28f2..87f5e3e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcTangentEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcTangentEvaluatorTest.java
@@ -76,7 +76,7 @@ public class ArcTangentEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("atan(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("atan(a)");
     
@@ -84,7 +84,7 @@ public class ArcTangentEvaluatorTest extends SolrTestCase {
     Object result = evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CeilingEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CeilingEvaluatorTest.java
index 38c494a..9a8a65e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CeilingEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CeilingEvaluatorTest.java
@@ -76,7 +76,7 @@ public class CeilingEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("ceil(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void ceilNoValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("ceil(a)");
     
@@ -85,7 +85,7 @@ public class CeilingEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void ceilNullValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("ceil(a)");
     
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CosineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CosineEvaluatorTest.java
index f5e9c6d..894d66e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CosineEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CosineEvaluatorTest.java
@@ -76,7 +76,7 @@ public class CosineEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("cos(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("cos(a)");
     
@@ -84,7 +84,7 @@ public class CosineEvaluatorTest extends SolrTestCase {
     Object result = evaluator.evaluate(new Tuple(values));
     assertNull(result);
   }
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CubedRootEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CubedRootEvaluatorTest.java
index 2d112ae..0776261 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CubedRootEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CubedRootEvaluatorTest.java
@@ -76,7 +76,7 @@ public class CubedRootEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("cbrt(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("cbrt(a)");
     
@@ -84,7 +84,7 @@ public class CubedRootEvaluatorTest extends SolrTestCase {
     Object result = evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/DivideEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/DivideEvaluatorTest.java
index 60d93ac..88e4b77 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/DivideEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/DivideEvaluatorTest.java
@@ -74,7 +74,7 @@ public class DivideEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("div(a)");
   }
   
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void divTwoFieldWithNulls() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("div(a,b)");
     
@@ -82,7 +82,7 @@ public class DivideEvaluatorTest extends SolrTestCase {
     evaluator.evaluate(new Tuple(values));
   }
   
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void divTwoFieldsWithNullDenominator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("div(a,b)");
     
@@ -91,7 +91,7 @@ public class DivideEvaluatorTest extends SolrTestCase {
     evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void divTwoFieldsWithNullNumerator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("div(a,b)");
     
@@ -101,7 +101,7 @@ public class DivideEvaluatorTest extends SolrTestCase {
   }
 
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void divTwoFieldsWithMissingDenominator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("div(a,b)");
     
@@ -110,7 +110,7 @@ public class DivideEvaluatorTest extends SolrTestCase {
     evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void divTwoFieldsWithMissingNumerator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("div(a,b)");
     
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/FloorEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/FloorEvaluatorTest.java
index 4320308..d51ef9e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/FloorEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/FloorEvaluatorTest.java
@@ -76,14 +76,14 @@ public class FloorEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("floor(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void floorNoValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("floor(a)");
     
     values.clear();
     Object result = evaluator.evaluate(new Tuple(values));
   }
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void floorNullValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("floor(a)");
     
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicCosineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicCosineEvaluatorTest.java
index 92d34ae..3c3f696 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicCosineEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicCosineEvaluatorTest.java
@@ -76,7 +76,7 @@ public class HyperbolicCosineEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("cosh(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("cosh(a)");
     
@@ -85,7 +85,7 @@ public class HyperbolicCosineEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicSineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicSineEvaluatorTest.java
index 259a846..d807c29 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicSineEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicSineEvaluatorTest.java
@@ -76,7 +76,7 @@ public class HyperbolicSineEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("sinh(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("sinh(a)");
     
@@ -85,7 +85,7 @@ public class HyperbolicSineEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicTangentEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicTangentEvaluatorTest.java
index a5bc93f..53cc6c0 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicTangentEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicTangentEvaluatorTest.java
@@ -76,7 +76,7 @@ public class HyperbolicTangentEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("tanh(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("tanh(a)");
     
@@ -85,7 +85,7 @@ public class HyperbolicTangentEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ModuloEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ModuloEvaluatorTest.java
index d72b55f..06a1338 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ModuloEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ModuloEvaluatorTest.java
@@ -74,7 +74,7 @@ public class ModuloEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("mod(a)");
   }
   
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void modTwoFieldWithNulls() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)");
     
@@ -82,7 +82,7 @@ public class ModuloEvaluatorTest extends SolrTestCase {
     evaluator.evaluate(new Tuple(values));
   }
   
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void modTwoFieldsWithNullDenominator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)");
     
@@ -91,7 +91,7 @@ public class ModuloEvaluatorTest extends SolrTestCase {
     evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void modTwoFieldsWithNullNumerator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)");
     
@@ -101,7 +101,7 @@ public class ModuloEvaluatorTest extends SolrTestCase {
   }
 
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void modTwoFieldsWithMissingDenominator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)");
     
@@ -110,7 +110,7 @@ public class ModuloEvaluatorTest extends SolrTestCase {
     evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void modTwoFieldsWithMissingNumerator() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)");
     
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java
index 49d0cfe..1bc3ccc 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/MultiplyEvaluatorTest.java
@@ -87,7 +87,7 @@ public class MultiplyEvaluatorTest extends SolrTestCase {
     Assert.assertEquals(6.5D, result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void multTwoFieldWithNulls() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mult(a,b)");
     Object result;
@@ -97,7 +97,7 @@ public class MultiplyEvaluatorTest extends SolrTestCase {
     Assert.assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void multTwoFieldsWithNull() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mult(a,b)");
     Object result;
@@ -121,7 +121,7 @@ public class MultiplyEvaluatorTest extends SolrTestCase {
     Assert.assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void multTwoFieldsWithMissingField() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("mult(a,b)");
     Object result;
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/NaturalLogEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/NaturalLogEvaluatorTest.java
index 5c15a5d..4592e47 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/NaturalLogEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/NaturalLogEvaluatorTest.java
@@ -78,7 +78,7 @@ public class NaturalLogEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("log(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void logNoValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("log(a)");
 
@@ -87,7 +87,7 @@ public class NaturalLogEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void logNullValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("log(a)");
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/PowerEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/PowerEvaluatorTest.java
index 2de054d..c4c02d3 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/PowerEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/PowerEvaluatorTest.java
@@ -94,7 +94,7 @@ public class PowerEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("pow(a)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void powTwoFieldWithNulls() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("pow(a,b)");
     
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/RoundEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/RoundEvaluatorTest.java
index 19809db..f6f2a96 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/RoundEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/RoundEvaluatorTest.java
@@ -80,7 +80,7 @@ public class RoundEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("round(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("round(a)");
     
@@ -88,7 +88,7 @@ public class RoundEvaluatorTest extends SolrTestCase {
     Object result = evaluator.evaluate(new Tuple(values));
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SineEvaluatorTest.java
index b8b29b9..fad1ba2 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SineEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SineEvaluatorTest.java
@@ -76,7 +76,7 @@ public class SineEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("sin(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("sin(a)");
     
@@ -85,7 +85,7 @@ public class SineEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SquareRootEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SquareRootEvaluatorTest.java
index 5608763..b4f6940 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SquareRootEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SquareRootEvaluatorTest.java
@@ -76,7 +76,7 @@ public class SquareRootEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("sqrt(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("sqrt(a)");
     
@@ -85,7 +85,7 @@ public class SquareRootEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SubtractEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SubtractEvaluatorTest.java
index 4d56b8d..48f1adb 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SubtractEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SubtractEvaluatorTest.java
@@ -74,7 +74,7 @@ public class SubtractEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("sub(a)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void subTwoFieldWithNulls() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("sub(a,b)");
     Object result;
@@ -84,7 +84,7 @@ public class SubtractEvaluatorTest extends SolrTestCase {
     Assert.assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void subTwoFieldsWithNull() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("sub(a,b)");
     Object result;
@@ -108,7 +108,7 @@ public class SubtractEvaluatorTest extends SolrTestCase {
     Assert.assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void subTwoFieldsWithMissingField() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("sub(a,b)");
     Object result;
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/TangentEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/TangentEvaluatorTest.java
index 8ad81dc..1452618 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/TangentEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/TangentEvaluatorTest.java
@@ -76,7 +76,7 @@ public class TangentEvaluatorTest extends SolrTestCase {
     factory.constructEvaluator("tan(a,b)");
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void noValue() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("tan(a)");
     
@@ -85,7 +85,7 @@ public class TangentEvaluatorTest extends SolrTestCase {
     assertNull(result);
   }
 
-  @Test(expected = IOException.class)
+  @Test(expected = NumberFormatException.class)
   public void nullValue() throws Exception{
     test(null);
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java
index 8bf5b57..5b434e6 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/UuidEvaluatorTest.java
@@ -43,10 +43,12 @@ public class UuidEvaluatorTest extends SolrTestCase {
   }
     
   @Test
-  public void isUuidType() throws Exception{
+  public void testUuid() throws Exception{
     StreamEvaluator evaluator = factory.constructEvaluator("uuid()");
-    
-    Assert.assertTrue(evaluator.evaluate(null) instanceof UUID);
-    Assert.assertTrue(evaluator.evaluate(new Tuple(values)) instanceof UUID);
-  }    
+    Assert.assertTrue(evaluator.evaluate(null) instanceof String);
+    String uuid = (String)evaluator.evaluate(null);
+    assertEquals(uuid.split("-").length, 5);
+    String uuid1 = (String)evaluator.evaluate(new Tuple(values));
+    assertNotEquals(uuid, uuid1);
+  }
 }


[lucene-solr] 01/03: SOLR-13625: Add CsvStream, TsvStream Streaming Expressions and supporting Stream Evaluators

Posted by jb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jbernste pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit d0674866edf109d5813cdf5c70968344373d9f77
Author: Joel Bernstein <jb...@apache.org>
AuthorDate: Thu Jul 25 10:57:30 2019 -0400

    SOLR-13625: Add CsvStream, TsvStream Streaming Expressions and supporting Stream Evaluators
---
 .../java/org/apache/solr/client/solrj/io/Lang.java |   5 +
 .../solr/client/solrj/io/eval/DateEvaluator.java   |  73 +++++++++
 .../solr/client/solrj/io/eval/DoubleEvaluator.java |  50 ++++++
 .../solr/client/solrj/io/eval/LongEvaluator.java   |  50 ++++++
 .../solr/client/solrj/io/stream/CsvStream.java     | 171 +++++++++++++++++++++
 .../solr/client/solrj/io/stream/TsvStream.java     |  84 ++++++++++
 .../org/apache/solr/client/solrj/io/TestLang.java  |   2 +-
 .../solrj/io/stream/StreamDecoratorTest.java       | 169 ++++++++++++++++++++
 8 files changed, 603 insertions(+), 1 deletion(-)

diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
index d64e320..60ce437 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/Lang.java
@@ -292,6 +292,11 @@ public class Lang {
         .withFunctionName("isNull", IsNullEvaluator.class)
         .withFunctionName("matches", MatchesEvaluator.class)
         .withFunctionName("projectToBorder", ProjectToBorderEvaluator.class)
+        .withFunctionName("parseCSV", CsvStream.class)
+        .withFunctionName("parseTSV", TsvStream.class)
+        .withFunctionName("double", DoubleEvaluator.class)
+        .withFunctionName("long", LongEvaluator.class)
+        .withFunctionName("dateTime", DateEvaluator.class)
 
         // Boolean Stream Evaluators
 
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DateEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DateEvaluator.java
new file mode 100644
index 0000000..582e3b6
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DateEvaluator.java
@@ -0,0 +1,73 @@
+/*
+ * 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.client.solrj.io.eval;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.Locale;
+
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class DateEvaluator extends RecursiveObjectEvaluator implements ManyValueWorker {
+  protected static final long serialVersionUID = 1L;
+
+  private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
+  private SimpleDateFormat parseFormat;
+
+
+  static {
+    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+  }
+
+  public DateEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+    super(expression, factory);
+  }
+
+  @Override
+  public Object doWork(Object values[]) throws IOException {
+    String sdate = values[0].toString();
+    String template = values[1].toString();
+
+    if(sdate.startsWith("\"")) {
+      sdate =sdate.replace("\"", "");
+    }
+
+    if(template.startsWith("\"")) {
+      template =template.replace("\"", "");
+    }
+
+
+    if(parseFormat == null) {
+      String timeZone = "UTC";
+      if(values.length == 3) {
+        timeZone = values[2].toString();
+      }
+      parseFormat = new SimpleDateFormat(template, Locale.US);
+      parseFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
+    }
+
+    try {
+      Date date = parseFormat.parse(sdate);
+      return dateFormat.format(date);
+    } catch(Exception e) {
+      throw new IOException(e);
+    }
+  }
+}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DoubleEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DoubleEvaluator.java
new file mode 100644
index 0000000..7fce45f
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DoubleEvaluator.java
@@ -0,0 +1,50 @@
+/*
+ * 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.client.solrj.io.eval;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class DoubleEvaluator extends RecursiveObjectEvaluator implements OneValueWorker {
+  protected static final long serialVersionUID = 1L;
+
+  public DoubleEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+    super(expression, factory);
+
+    if(1 != containedEvaluators.size()){
+      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting exactly 1 value but found %d",expression,containedEvaluators.size()));
+    }
+  }
+
+  @Override
+  public Object doWork(Object value){
+    if(null == value){
+      return null;
+    }
+    else if(value instanceof List){
+      return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
+    }
+    else{
+      return Double.valueOf(value.toString());
+    }
+  }
+}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LongEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LongEvaluator.java
new file mode 100644
index 0000000..4547d8c
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LongEvaluator.java
@@ -0,0 +1,50 @@
+/*
+ * 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.client.solrj.io.eval;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class LongEvaluator extends RecursiveObjectEvaluator implements OneValueWorker {
+  protected static final long serialVersionUID = 1L;
+
+  public LongEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+    super(expression, factory);
+
+    if(1 != containedEvaluators.size()){
+      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting exactly 1 value but found %d",expression,containedEvaluators.size()));
+    }
+  }
+
+  @Override
+  public Object doWork(Object value){
+    if(null == value){
+      return null;
+    }
+    else if(value instanceof List){
+      return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
+    }
+    else{
+      return Long.valueOf(value.toString());
+    }
+  }
+}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CsvStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CsvStream.java
new file mode 100644
index 0000000..b8c479e
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CsvStream.java
@@ -0,0 +1,171 @@
+/*
+ * 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.client.solrj.io.stream;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.solr.client.solrj.io.Tuple;
+import org.apache.solr.client.solrj.io.comp.StreamComparator;
+import org.apache.solr.client.solrj.io.stream.expr.Explanation;
+import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
+import org.apache.solr.client.solrj.io.stream.expr.Expressible;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExplanation;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class CsvStream extends TupleStream implements Expressible {
+
+  private static final long serialVersionUID = 1;
+  private String[] headers;
+  private String currentFile;
+  private int lineNumber;
+
+  protected TupleStream originalStream;
+
+  public CsvStream(StreamExpression expression,StreamFactory factory) throws IOException {
+    // grab all parameters out
+    List<StreamExpression> streamExpressions = factory.getExpressionOperandsRepresentingTypes(expression, Expressible.class, TupleStream.class);
+
+    // validate expression contains only what we want.
+    if(expression.getParameters().size() != streamExpressions.size()){
+      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - unknown operands found", expression));
+    }
+
+    if(1 != streamExpressions.size()){
+      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting a single stream but found %d",expression, streamExpressions.size()));
+    }
+
+    init(factory.constructStream(streamExpressions.get(0)));
+  }
+
+  private void init(TupleStream stream) throws IOException{
+    this.originalStream = stream;
+  }
+
+  @Override
+  public StreamExpression toExpression(StreamFactory factory) throws IOException{
+    return toExpression(factory, true);
+  }
+
+  private StreamExpression toExpression(StreamFactory factory, boolean includeStreams) throws IOException {
+    // function name
+    StreamExpression expression = new StreamExpression(factory.getFunctionName(this.getClass()));
+
+    if(includeStreams){
+      // streams
+      if(originalStream instanceof Expressible){
+        expression.addParameter(((Expressible)originalStream).toExpression(factory));
+      }
+      else{
+        throw new IOException("This CsvStream contains a non-expressible TupleStream - it cannot be converted to an expression");
+      }
+    }
+    else{
+      expression.addParameter("<stream>");
+    }
+
+    return expression;
+  }
+
+  @Override
+  public Explanation toExplanation(StreamFactory factory) throws IOException {
+
+    return new StreamExplanation(getStreamNodeId().toString())
+        .withChildren(new Explanation[] {
+            originalStream.toExplanation(factory)
+            // we're not including that this is wrapped with a ReducerStream stream because that's just an implementation detail
+        })
+        .withFunctionName(factory.getFunctionName(this.getClass()))
+        .withImplementingClass(this.getClass().getName())
+        .withExpressionType(ExpressionType.STREAM_DECORATOR)
+        .withExpression(toExpression(factory, false).toString());
+  }
+
+  public void setStreamContext(StreamContext context) {
+    this.originalStream.setStreamContext(context);
+  }
+
+  public List<TupleStream> children() {
+    List<TupleStream> l =  new ArrayList<TupleStream>();
+    l.add(originalStream);
+    return l;
+  }
+
+  public void open() throws IOException {
+    originalStream.open();
+  }
+
+  public void close() throws IOException {
+    originalStream.close();
+  }
+
+  public Tuple read() throws IOException {
+    Tuple tuple = originalStream.read();
+    ++lineNumber;
+    if(tuple.EOF) {
+      return tuple;
+    } else {
+      String file = tuple.getString("file");
+      String line = tuple.getString("line");
+      if (file.equals(currentFile)) {
+        String[] fields = split(line);
+        if(fields.length != headers.length) {
+          throw new IOException("Headers and lines must have the same number of fields [file:"+file+" line number:"+lineNumber+"]");
+        }
+        Tuple out = new Tuple(new HashMap());
+        for(int i=0; i<headers.length; i++) {
+          if(fields[i] != null && fields[i].length() > 0) {
+            out.put(headers[i], fields[i]);
+          }
+        }
+        return out;
+      } else {
+        this.currentFile = file;
+        this.headers = split(line);
+        this.lineNumber = 1; //New file so reset the lineNumber
+        return read();
+      }
+    }
+  }
+
+  protected String[] split(String line) {
+    String[] fields = line.split(",(?=([^\"]|\"[^\"]*\")*$)",-1);
+    for(int i=0; i<fields.length; i++) {
+      String f = fields[i];
+      if(f.startsWith("\"") && f.endsWith("\"")) {
+        f = f.substring(1, f.length()-1);
+        fields[i] = f;
+      }
+    }
+
+    return fields;
+  }
+
+  /** Return the stream sort - ie, the order in which records are returned */
+  public StreamComparator getStreamSort(){
+    return originalStream.getStreamSort();
+  }
+
+  public int getCost() {
+    return 0;
+  }
+
+}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java
new file mode 100644
index 0000000..7b5d0d8
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TsvStream.java
@@ -0,0 +1,84 @@
+/*
+ * 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.client.solrj.io.stream;
+
+import java.io.IOException;
+
+import org.apache.solr.client.solrj.io.stream.expr.Explanation;
+import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
+import org.apache.solr.client.solrj.io.stream.expr.Expressible;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExplanation;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class TsvStream extends CsvStream implements Expressible {
+
+  private static final long serialVersionUID = 1;
+
+  public TsvStream(StreamExpression expression,StreamFactory factory) throws IOException {
+    super(expression, factory);
+  }
+
+
+  @Override
+  public StreamExpression toExpression(StreamFactory factory) throws IOException{
+    return toExpression(factory, true);
+  }
+
+  private StreamExpression toExpression(StreamFactory factory, boolean includeStreams) throws IOException {
+    // function name
+    StreamExpression expression = new StreamExpression(factory.getFunctionName(this.getClass()));
+
+    if(includeStreams){
+      // streams
+      if(originalStream instanceof Expressible){
+        expression.addParameter(((Expressible)originalStream).toExpression(factory));
+      }
+      else{
+        throw new IOException("This TsvStream contains a non-expressible TupleStream - it cannot be converted to an expression");
+      }
+    }
+    else{
+      expression.addParameter("<stream>");
+    }
+
+    return expression;
+  }
+
+  @Override
+  public Explanation toExplanation(StreamFactory factory) throws IOException {
+
+    return new StreamExplanation(getStreamNodeId().toString())
+        .withChildren(new Explanation[] {
+            originalStream.toExplanation(factory)
+            // we're not including that this is wrapped with a ReducerStream stream because that's just an implementation detail
+        })
+        .withFunctionName(factory.getFunctionName(this.getClass()))
+        .withImplementingClass(this.getClass().getName())
+        .withExpressionType(ExpressionType.STREAM_DECORATOR)
+        .withExpression(toExpression(factory, false).toString());
+  }
+
+  protected String[] split(String line) {
+    String[] parts = line.split("\\t", -1);
+    for(String s : parts) {
+      System.out.println("part:"+s+":"+line.length()+":"+line+":");
+    }
+    return parts;
+  }
+
+}
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/TestLang.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/TestLang.java
index 60ac6ec..f2e6a42 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/TestLang.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/TestLang.java
@@ -76,7 +76,7 @@ public class TestLang extends SolrTestCase {
       "getAmplitude", "getPhase", "getAngularFrequency", "enclosingDisk", "getCenter", "getRadius",
       "getSupportPoints", "pairSort", "log10", "plist", "recip", "pivot", "ltrim", "rtrim", "export",
       "zplot", "natural", "repeat", "movingMAD", "hashRollup", "noop", "var", "stddev", "recNum", "isNull",
-      "notNull", "matches", "projectToBorder"};
+      "notNull", "matches", "projectToBorder", "double", "long", "parseCSV", "parseTSV", "dateTime"};
 
   @Test
   public void testLang() {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
index 504b74b..65815e1 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
@@ -3151,6 +3151,175 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
     }
   }
 
+
+  @Test
+  public void testParseCSV() throws Exception {
+    String expr = "parseCSV(list(tuple(file=\"file1\", line=\"a,b,c\"), " +
+        "                        tuple(file=\"file1\", line=\"1,2,3\")," +
+        "                        tuple(file=\"file1\", line=\"\\\"hello, world\\\",9000,20\")," +
+        "                        tuple(file=\"file2\", line=\"field_1,field_2,field_3\"), "+
+        "                        tuple(file=\"file2\", line=\"8,9,\")))";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    assertEquals(tuples.size(),  3);
+    assertEquals(tuples.get(0).getString("a"), "1");
+    assertEquals(tuples.get(0).getString("b"), "2");
+    assertEquals(tuples.get(0).getString("c"), "3");
+
+    assertEquals(tuples.get(1).getString("a"), "hello, world");
+    assertEquals(tuples.get(1).getString("b"), "9000");
+    assertEquals(tuples.get(1).getString("c"), "20");
+
+    assertEquals(tuples.get(2).getString("field_1"), "8");
+    assertEquals(tuples.get(2).getString("field_2"), "9");
+    assertNull(tuples.get(2).get("field_3"));
+  }
+
+
+  @Test
+  public void testParseTSV() throws Exception {
+    String expr = "parseTSV(list(tuple(file=\"file1\", line=\"a\tb\tc\"), " +
+        "                        tuple(file=\"file1\", line=\"1\t2\t3\")," +
+        "                        tuple(file=\"file1\", line=\"hello, world\t9000\t20\")," +
+        "                        tuple(file=\"file2\", line=\"field_1\tfield_2\tfield_3\"), "+
+        "                        tuple(file=\"file2\", line=\"8\t\t9\")))";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    assertEquals(tuples.size(),  3);
+    assertEquals(tuples.get(0).getString("a"), "1");
+    assertEquals(tuples.get(0).getString("b"), "2");
+    assertEquals(tuples.get(0).getString("c"), "3");
+
+    assertEquals(tuples.get(1).getString("a"), "hello, world");
+    assertEquals(tuples.get(1).getString("b"), "9000");
+    assertEquals(tuples.get(1).getString("c"), "20");
+
+    assertEquals(tuples.get(2).getString("field_1"), "8");
+    assertNull(tuples.get(2).get("field_2"));
+    assertEquals(tuples.get(2).getString("field_3"), "9");
+
+  }
+
+
+  @Test
+  public void testDateTime() throws Exception {
+    String expr = "select(list(tuple(a=20001011:10:11:01), tuple(a=20071011:14:30:20)), dateTime(a, yyyyMMdd:kk:mm:ss) as date)";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    String date = (String)tuples.get(0).get("date");
+    assertEquals(date, "2000-10-11T10:11:01Z");
+    date = (String)tuples.get(1).get("date");
+    assertEquals(date, "2007-10-11T14:30:20Z");
+  }
+
+  @Test
+  public void testDateTimeTZ() throws Exception {
+    String expr = "select(list(tuple(a=20001011), tuple(a=20071011)), dateTime(a, yyyyMMdd, UTC) as date, dateTime(a, yyyyMMdd, EST) as date1, dateTime(a, yyyyMMdd) as date2)";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    String date = (String)tuples.get(0).get("date");
+    String date1 = (String)tuples.get(0).get("date1");
+    String date2 = (String)tuples.get(0).get("date2");
+
+    assertEquals(date, "2000-10-11T00:00:00Z");
+    assertEquals(date1, "2000-10-11T05:00:00Z");
+    assertEquals(date2, "2000-10-11T00:00:00Z");
+
+
+    date = (String)tuples.get(1).get("date");
+    date1 = (String)tuples.get(1).get("date1");
+    date2 = (String)tuples.get(1).get("date2");
+
+    assertEquals(date, "2007-10-11T00:00:00Z");
+    assertEquals(date1, "2007-10-11T05:00:00Z");
+    assertEquals(date2, "2007-10-11T00:00:00Z");
+  }
+
+
+
+  @Test
+  public void testDoubleLong() throws Exception {
+    String expr = "select(tuple(d=\"1.1\", l=\"5000\"), double(d) as d, long(l) as l)";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    assertEquals(tuples.size(),  1);
+    assertTrue(tuples.get(0).get("d") instanceof Double);
+    assertTrue(tuples.get(0).get("l") instanceof Long);
+
+    assertEquals(tuples.get(0).getDouble("d"), 1.1D, 0);
+    assertEquals(tuples.get(0).getLong("l").longValue(), 5000L);
+
+  }
+
+
+  public void testDoubleLongArray() throws Exception {
+    String expr = "let(a=list(tuple(d=\"1.1\", l=\"5000\"), tuple(d=\"1.3\", l=\"7000\"))," +
+        "              b=col(a, d)," +
+        "              c=col(a, l)," +
+        "              tuple(doubles=double(b)," +
+        "                    longs=long(c)))";
+    ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
+    paramsLoc.set("expr", expr);
+    paramsLoc.set("qt", "/stream");
+
+    String url = cluster.getJettySolrRunners().get(0).getBaseUrl().toString() + "/" + COLLECTIONORALIAS;
+    TupleStream solrStream = new SolrStream(url, paramsLoc);
+
+    StreamContext context = new StreamContext();
+    solrStream.setStreamContext(context);
+    List<Tuple> tuples = getTuples(solrStream);
+    assertEquals(tuples.size(),  1);
+
+    List<Double> doubles = (List<Double>)tuples.get(0).get("doubles");
+    List<Long> longs = (List<Long>)tuples.get(0).get("longs");
+    assertEquals(doubles.get(0), 1.1, 0);
+    assertEquals(doubles.get(1), 1.3, 0);
+
+    assertEquals(longs.get(0).longValue(), 5000L);
+    assertEquals(longs.get(1).longValue(), 7000L);
+  }
+
+
   @Test
   public void testCommitStream() throws Exception {