diff --git a/solr/core/src/java/org/apache/solr/handler/GraphHandler.java b/solr/core/src/java/org/apache/solr/handler/GraphHandler.java index a6e2ce149bf..a203a4fac30 100644 --- a/solr/core/src/java/org/apache/solr/handler/GraphHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/GraphHandler.java @@ -113,6 +113,7 @@ public class GraphHandler extends RequestHandlerBase implements SolrCoreAware, P .withFunctionName("update", UpdateStream.class) .withFunctionName("jdbc", JDBCStream.class) .withFunctionName("intersect", IntersectStream.class) + .withFunctionName("select", SelectStream.class) .withFunctionName("complement", ComplementStream.class) .withFunctionName("daemon", DaemonStream.class) .withFunctionName("topic", TopicStream.class) diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java index 10bd6340378..52a6a1ed392 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java @@ -275,7 +275,7 @@ public class GatherNodesStream extends TupleStream implements Expressible { // collection expression.addParameter(collection); - if(includeStreams){ + if(includeStreams && !(tupleStream instanceof NodeStream)){ if(tupleStream instanceof Expressible){ expression.addParameter(((Expressible)tupleStream).toExpression(factory)); } @@ -311,7 +311,14 @@ public class GatherNodesStream extends TupleStream implements Expressible { if(maxDocFreq > -1) { expression.addParameter(new StreamExpressionNamedParameter("maxDocFreq", Integer.toString(maxDocFreq))); } - expression.addParameter(new StreamExpressionNamedParameter("walk", traverseFrom+"->"+traverseTo)); + if(tupleStream instanceof NodeStream) { + NodeStream nodeStream = (NodeStream)tupleStream; + expression.addParameter(new StreamExpressionNamedParameter("walk", nodeStream.toString() + "->" + traverseTo)); + + } else { + expression.addParameter(new StreamExpressionNamedParameter("walk", traverseFrom + "->" + traverseTo)); + } + expression.addParameter(new StreamExpressionNamedParameter("trackTraversal", Boolean.toString(trackTraversal))); StringBuilder buf = new StringBuilder(); @@ -641,6 +648,19 @@ public class GatherNodesStream extends TupleStream implements Expressible { return new Tuple(map); } } + + public String toString() { + StringBuilder builder = new StringBuilder(); + boolean comma = false; + for(String s : ids) { + if(comma) { + builder.append(","); + } + builder.append(s); + comma = true; + } + return builder.toString(); + } @Override public Explanation toExplanation(StreamFactory factory) throws IOException { diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java index dd02175e963..8aba89c2e66 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java @@ -125,17 +125,17 @@ public class CloudSolrStream extends TupleStream implements Expressible { List namedParams = factory.getNamedOperands(expression); StreamExpressionNamedParameter aliasExpression = factory.getNamedOperand(expression, "aliases"); StreamExpressionNamedParameter zkHostExpression = factory.getNamedOperand(expression, "zkHost"); - + + // Collection Name + if(null == collectionName){ + throw new IOException(String.format(Locale.ROOT,"invalid expression %s - collectionName expected as first operand",expression)); + } + // Validate there are no unknown parameters - zkHost and alias are namedParameter so we don't need to count it twice if(expression.getParameters().size() != 1 + namedParams.size()){ throw new IOException(String.format(Locale.ROOT,"invalid expression %s - unknown operands found",expression)); } - // Collection Name - if(null == collectionName){ - throw new IOException(String.format(Locale.ROOT,"invalid expression %s - collectionName expected as first operand",expression)); - } - // Named parameters - passed directly to solr as solrparams if(0 == namedParams.size()){ throw new IOException(String.format(Locale.ROOT,"invalid expression %s - at least one named parameter expected. eg. 'q=*:*'",expression)); @@ -257,15 +257,20 @@ public class CloudSolrStream extends TupleStream implements Expressible { // If the comparator is null then it was not explicitly set so we will create one using the sort parameter // of the query. While doing this we will also take into account any aliases such that if we are sorting on // fieldA but fieldA is aliased to alias.fieldA then the comparater will be against alias.fieldA. - String fls = String.join(",", params.getParams("fl")); - if (fls == null) { - throw new IOException("fl param expected for a stream"); + + if (params.get("q") == null) { + throw new IOException("q param expected for search function"); } - String sorts = String.join(",", params.getParams("sort")); - if (sorts == null) { - throw new IOException("sort param expected for a stream"); + if (params.getParams("fl") == null) { + throw new IOException("fl param expected for search function"); } + String fls = String.join(",", params.getParams("fl")); + + if (params.getParams("sort") == null) { + throw new IOException("sort param expected for search function"); + } + String sorts = String.join(",", params.getParams("sort")); this.comp = parseComp(sorts, fls); } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java index ae04a85970c..86124dedf3c 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java @@ -477,6 +477,9 @@ public class FacetStream extends TupleStream implements Expressible { String bucketName = _buckets[level].toString(); NamedList nl = (NamedList)facets.get(bucketName); + if(nl == null) { + return; + } List allBuckets = (List)nl.get("buckets"); for(int b=0; b