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 2016/01/12 21:47:33 UTC
svn commit: r1724319 - in /lucene/dev/trunk/solr: CHANGES.txt
core/src/java/org/apache/solr/handler/SQLHandler.java
core/src/test/org/apache/solr/handler/TestSQLHandler.java
Author: jbernste
Date: Tue Jan 12 20:47:33 2016
New Revision: 1724319
URL: http://svn.apache.org/viewvc?rev=1724319&view=rev
Log:
SOLR-8002: Add column alias support to the Parallel SQL Interface
Modified:
lucene/dev/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SQLHandler.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1724319&r1=1724318&r2=1724319&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Tue Jan 12 20:47:33 2016
@@ -130,6 +130,9 @@ New Features
* SOLR-8479: Add JDBCStream to Streaming API and Streaming Expressions for integration with external data sources
(Dennis Gove)
+* SOLR-8002: Add column alias support to the Parallel SQL Interface (Joel Bernstein)
+
+
Bug Fixes
----------------------
* SOLR-8386: Add field option in the new admin UI schema page loads up even when no schemaFactory has been
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SQLHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SQLHandler.java?rev=1724319&r1=1724318&r2=1724319&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SQLHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SQLHandler.java Tue Jan 12 20:47:33 2016
@@ -149,6 +149,7 @@ public class SQLHandler extends RequestH
SQLVisitor sqlVistor = new SQLVisitor(new StringBuilder());
sqlVistor.process(statement, new Integer(0));
+ sqlVistor.reverseAliases();
TupleStream sqlStream = null;
@@ -234,13 +235,13 @@ public class SQLHandler extends RequestH
// Once we make this a Expressionable the problem will be solved.
if(sqlVisitor.havingExpression != null) {
- tupleStream = new HavingStream(tupleStream, sqlVisitor.havingExpression);
+ tupleStream = new HavingStream(tupleStream, sqlVisitor.havingExpression, sqlVisitor.reverseColumnAliases );
}
if(sqlVisitor.sorts != null && sqlVisitor.sorts.size() > 0) {
- if(!sortsEqual(buckets, sortDirection, sqlVisitor.sorts)) {
+ if(!sortsEqual(buckets, sortDirection, sqlVisitor.sorts, sqlVisitor.reverseColumnAliases)) {
int limit = sqlVisitor.limit == -1 ? 100 : sqlVisitor.limit;
- StreamComparator comp = getComp(sqlVisitor.sorts);
+ StreamComparator comp = getComp(sqlVisitor.sorts, sqlVisitor.reverseColumnAliases);
//Rank the Tuples
//If parallel stream is used ALL the Rolled up tuples from the workers will be ranked
//Providing a true Top or Bottom.
@@ -254,6 +255,10 @@ public class SQLHandler extends RequestH
}
}
+ if(sqlVisitor.hasColumnAliases) {
+ tupleStream = new SelectStream(tupleStream, sqlVisitor.columnAliases);
+ }
+
return tupleStream;
}
@@ -277,7 +282,7 @@ public class SQLHandler extends RequestH
StreamComparator comp = null;
if(sqlVisitor.sorts != null && sqlVisitor.sorts.size() > 0) {
- StreamComparator[] adjustedSorts = adjustSorts(sqlVisitor.sorts, buckets);
+ StreamComparator[] adjustedSorts = adjustSorts(sqlVisitor.sorts, buckets, sqlVisitor.reverseColumnAliases);
// Because of the way adjustSorts works we know that each FieldComparator has a single
// field name. For this reason we can just look at the leftFieldName
FieldEqualitor[] fieldEqualitors = new FieldEqualitor[adjustedSorts.length];
@@ -364,18 +369,22 @@ public class SQLHandler extends RequestH
tupleStream = new LimitStream(tupleStream, sqlVisitor.limit);
}
+ if(sqlVisitor.hasColumnAliases) {
+ tupleStream = new SelectStream(tupleStream, sqlVisitor.columnAliases);
+ }
+
return tupleStream;
}
- private static StreamComparator[] adjustSorts(List<SortItem> sorts, Bucket[] buckets) throws IOException {
+ private static StreamComparator[] adjustSorts(List<SortItem> sorts, Bucket[] buckets, Map<String, String> reverseColumnAliases) throws IOException {
List<FieldComparator> adjustedSorts = new ArrayList();
Set<String> bucketFields = new HashSet();
Set<String> sortFields = new HashSet();
for(SortItem sortItem : sorts) {
- sortFields.add(getSortField(sortItem));
- adjustedSorts.add(new FieldComparator(getSortField(sortItem),
+ sortFields.add(getSortField(sortItem, reverseColumnAliases));
+ adjustedSorts.add(new FieldComparator(getSortField(sortItem, reverseColumnAliases),
ascDescComp(sortItem.getOrdering().toString())));
}
@@ -384,7 +393,7 @@ public class SQLHandler extends RequestH
}
for(SortItem sortItem : sorts) {
- String sortField = getSortField(sortItem);
+ String sortField = getSortField(sortItem, reverseColumnAliases);
if(!bucketFields.contains(sortField)) {
throw new IOException("All sort fields must be in the field list.");
}
@@ -431,7 +440,7 @@ public class SQLHandler extends RequestH
sorts[i] = new FieldComparator("index", ComparatorOrder.ASCENDING);
}
} else {
- StreamComparator[] comps = adjustSorts(sqlVisitor.sorts, buckets);
+ StreamComparator[] comps = adjustSorts(sqlVisitor.sorts, buckets, sqlVisitor.reverseColumnAliases);
sorts = new FieldComparator[comps.length];
for(int i=0; i<comps.length; i++) {
sorts[i] = (FieldComparator)comps[i];
@@ -450,7 +459,7 @@ public class SQLHandler extends RequestH
tupleStream = new LimitStream(tupleStream, sqlVisitor.limit);
}
- return new SelectStream(tupleStream, sqlVisitor.fields);
+ return new SelectStream(tupleStream, sqlVisitor.columnAliases);
}
private static TupleStream doGroupByWithAggregatesFacets(SQLVisitor sqlVisitor) throws IOException {
@@ -480,7 +489,7 @@ public class SQLHandler extends RequestH
sorts[i] = new FieldComparator("index", ComparatorOrder.ASCENDING);
}
} else {
- sorts = getComps(sqlVisitor.sorts);
+ sorts = getComps(sqlVisitor.sorts, sqlVisitor.reverseColumnAliases);
}
TupleStream tupleStream = new FacetStream(zkHost,
@@ -492,7 +501,7 @@ public class SQLHandler extends RequestH
limit);
if(sqlVisitor.havingExpression != null) {
- tupleStream = new HavingStream(tupleStream, sqlVisitor.havingExpression);
+ tupleStream = new HavingStream(tupleStream, sqlVisitor.havingExpression, sqlVisitor.reverseColumnAliases);
}
if(sqlVisitor.limit > 0)
@@ -500,6 +509,10 @@ public class SQLHandler extends RequestH
tupleStream = new LimitStream(tupleStream, sqlVisitor.limit);
}
+ if(sqlVisitor.hasColumnAliases) {
+ tupleStream = new SelectStream(tupleStream, sqlVisitor.columnAliases);
+ }
+
return tupleStream;
}
@@ -559,7 +572,7 @@ public class SQLHandler extends RequestH
if (comma) {
siBuf.append(",");
}
- siBuf.append(getSortField(sortItem) + " " + ascDesc(sortItem.getOrdering().toString()));
+ siBuf.append(getSortField(sortItem, sqlVisitor.reverseColumnAliases) + " " + ascDesc(sortItem.getOrdering().toString()));
}
} else {
if(sqlVisitor.limit < 0) {
@@ -585,17 +598,25 @@ public class SQLHandler extends RequestH
params.put("sort", siBuf.toString());
}
+ TupleStream tupleStream = null;
+
if(sqlVisitor.limit > -1) {
params.put("rows", Integer.toString(sqlVisitor.limit));
- return new LimitStream(new CloudSolrStream(zkHost, collection, params), sqlVisitor.limit);
+ tupleStream = new LimitStream(new CloudSolrStream(zkHost, collection, params), sqlVisitor.limit);
} else {
//Only use the export handler when no limit is specified.
params.put(CommonParams.QT, "/export");
- return new CloudSolrStream(zkHost, collection, params);
+ tupleStream = new CloudSolrStream(zkHost, collection, params);
+ }
+
+ if(sqlVisitor.hasColumnAliases) {
+ return new SelectStream(tupleStream, sqlVisitor.columnAliases);
+ } else {
+ return tupleStream;
}
}
- private static boolean sortsEqual(Bucket[] buckets, String direction, List<SortItem> sortItems) {
+ private static boolean sortsEqual(Bucket[] buckets, String direction, List<SortItem> sortItems, Map<String, String> reverseColumnAliases) {
if(buckets.length != sortItems.size()) {
return false;
}
@@ -603,7 +624,7 @@ public class SQLHandler extends RequestH
for(int i=0; i< buckets.length; i++) {
Bucket bucket = buckets[i];
SortItem sortItem = sortItems.get(i);
- if(!bucket.toString().equals(getSortField(sortItem))) {
+ if(!bucket.toString().equals(getSortField(sortItem, reverseColumnAliases))) {
return false;
}
@@ -635,6 +656,10 @@ public class SQLHandler extends RequestH
params,
metrics);
+ if(sqlVisitor.hasColumnAliases) {
+ tupleStream = new SelectStream(tupleStream, sqlVisitor.columnAliases);
+ }
+
return tupleStream;
}
@@ -690,13 +715,13 @@ public class SQLHandler extends RequestH
}
}
- private static StreamComparator getComp(List<SortItem> sortItems) {
+ private static StreamComparator getComp(List<SortItem> sortItems, Map<String, String> reverseColumnAliases) {
FieldComparator[] comps = new FieldComparator[sortItems.size()];
for(int i=0; i<sortItems.size(); i++) {
SortItem sortItem = sortItems.get(i);
String ordering = sortItem.getOrdering().toString();
ComparatorOrder comparatorOrder = ascDescComp(ordering);
- String sortKey = getSortField(sortItem);
+ String sortKey = getSortField(sortItem, reverseColumnAliases);
comps[i] = new FieldComparator(sortKey, comparatorOrder);
}
@@ -707,13 +732,13 @@ public class SQLHandler extends RequestH
}
}
- private static FieldComparator[] getComps(List<SortItem> sortItems) {
+ private static FieldComparator[] getComps(List<SortItem> sortItems, Map<String, String> reverseColumnAliases) {
FieldComparator[] comps = new FieldComparator[sortItems.size()];
for(int i=0; i<sortItems.size(); i++) {
SortItem sortItem = sortItems.get(i);
String ordering = sortItem.getOrdering().toString();
ComparatorOrder comparatorOrder = ascDescComp(ordering);
- String sortKey = getSortField(sortItem);
+ String sortKey = getSortField(sortItem, reverseColumnAliases);
comps[i] = new FieldComparator(sortKey, comparatorOrder);
}
@@ -884,6 +909,9 @@ public class SQLHandler extends RequestH
public boolean groupByQuery;
public Expression havingExpression;
public boolean isDistinct;
+ public boolean hasColumnAliases;
+ public Map<String, String> columnAliases = new HashMap();
+ public Map<String, String> reverseColumnAliases = new HashMap();
public SQLVisitor(StringBuilder builder) {
this.builder = builder;
@@ -893,6 +921,28 @@ public class SQLHandler extends RequestH
throw new UnsupportedOperationException("not yet implemented: " + node);
}
+ protected void reverseAliases() {
+ for(String key : columnAliases.keySet()) {
+ reverseColumnAliases.put(columnAliases.get(key), key);
+ }
+
+ //Handle the group by.
+ List<String> newGroups = new ArrayList();
+
+ for(String g : groupBy) {
+ if (reverseColumnAliases.containsKey(g)) {
+ newGroups.add(reverseColumnAliases.get(g));
+ } else {
+ newGroups.add(g);
+ }
+ }
+
+ groupBy = newGroups;
+ }
+
+
+
+
protected Void visitUnnest(Unnest node, Integer indent) {
return null;
}
@@ -966,8 +1016,6 @@ public class SQLHandler extends RequestH
return null;
}
-
-
protected Void visitComparisonExpression(ComparisonExpression node, Integer index) {
String field = node.getLeft().toString();
String value = node.getRight().toString();
@@ -1029,6 +1077,11 @@ public class SQLHandler extends RequestH
fields.add(field);
if(node.getAlias().isPresent()) {
+ String alias = node.getAlias().get();
+ columnAliases.put(field, alias);
+ hasColumnAliases = true;
+ } else {
+ columnAliases.put(field, field);
}
return null;
@@ -1078,7 +1131,7 @@ public class SQLHandler extends RequestH
}
}
- private static String getSortField(SortItem sortItem)
+ private static String getSortField(SortItem sortItem, Map<String, String> reverseColumnAliases)
{
String field;
Expression ex = sortItem.getSortKey();
@@ -1105,6 +1158,10 @@ public class SQLHandler extends RequestH
field = stripSingleQuotes(stringLiteral.toString());
}
+ if(reverseColumnAliases.containsKey(field)) {
+ field = reverseColumnAliases.get(field);
+ }
+
return field;
}
@@ -1238,9 +1295,9 @@ public class SQLHandler extends RequestH
private HavingVisitor havingVisitor;
private Expression havingExpression;
- public HavingStream(TupleStream stream, Expression havingExpression) {
+ public HavingStream(TupleStream stream, Expression havingExpression, Map<String, String> reverseAliasMap) {
this.stream = stream;
- this.havingVisitor = new HavingVisitor();
+ this.havingVisitor = new HavingVisitor(reverseAliasMap);
this.havingExpression = havingExpression;
}
@@ -1282,6 +1339,12 @@ public class SQLHandler extends RequestH
private static class HavingVisitor extends AstVisitor<Boolean, Tuple> {
+ private Map<String,String> reverseAliasMap;
+
+ public HavingVisitor(Map<String, String> reverseAliasMap) {
+ this.reverseAliasMap = reverseAliasMap;
+ }
+
protected Boolean visitLogicalBinaryExpression(LogicalBinaryExpression node, Tuple tuple) {
Boolean b = process(node.getLeft(), tuple);
@@ -1304,6 +1367,11 @@ public class SQLHandler extends RequestH
protected Boolean visitComparisonExpression(ComparisonExpression node, Tuple tuple) {
String field = getHavingField(node.getLeft());
+
+ if(reverseAliasMap.containsKey(field)) {
+ field = reverseAliasMap.get(field);
+ }
+
double d = Double.parseDouble(node.getRight().toString());
double td = tuple.getDouble(field);
ComparisonExpression.Type t = node.getType();
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java?rev=1724319&r1=1724318&r2=1724319&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java Tue Jan 12 20:47:33 2016
@@ -320,6 +320,56 @@ public class TestSQLHandler extends Abst
assert(tuple.getLong("field_i") == 7);
assert(tuple.get("str_s").equals("a"));
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
+ params.put("stmt", "select id as myId, field_i as myInt, str_s as myString from collection1 where text='XXXX' AND id='(1 2 3)' order by myInt desc");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ assert(tuples.size() == 3);
+
+ tuple = tuples.get(0);
+ assert(tuple.getLong("myId") == 3);
+ assert(tuple.getLong("myInt") == 20);
+ assert(tuple.get("myString").equals("a"));
+
+ tuple = tuples.get(1);
+ assert(tuple.getLong("myId") == 2);
+ assert(tuple.getLong("myInt") == 8);
+ assert(tuple.get("myString").equals("b"));
+
+ tuple = tuples.get(2);
+ assert(tuple.getLong("myId") == 1);
+ assert(tuple.getLong("myInt") == 7);
+ assert(tuple.get("myString").equals("a"));
+
+
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
+ params.put("stmt", "select id as myId, field_i as myInt, str_s as myString from collection1 where text='XXXX' AND id='(1 2 3)' order by field_i desc");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ assert(tuples.size() == 3);
+
+ tuple = tuples.get(0);
+ assert(tuple.getLong("myId") == 3);
+ assert(tuple.getLong("myInt") == 20);
+ assert(tuple.get("myString").equals("a"));
+
+ tuple = tuples.get(1);
+ assert(tuple.getLong("myId") == 2);
+ assert(tuple.getLong("myInt") == 8);
+ assert(tuple.get("myString").equals("b"));
+
+ tuple = tuples.get(2);
+ assert(tuple.getLong("myId") == 1);
+ assert(tuple.getLong("myInt") == 7);
+ assert(tuple.get("myString").equals("a"));
+
+
} finally {
delete();
}
@@ -559,6 +609,33 @@ public class TestSQLHandler extends Abst
assert(tuple.getDouble("max(field_i)") == 20);
assert(tuple.getDouble("avg(field_i)") == 13.5D);
+
+ params.put(CommonParams.QT, "/sql");
+ params.put("stmt", "select str_s as myString, 'count(*)', sum('field_i') as sum, min(field_i), max(field_i), avg(field_i) from collection1 where text='XXXX' group by 'str_s' order by sum asc limit 2");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ //Only two results because of the limit.
+ assert(tuples.size() == 2);
+
+ tuple = tuples.get(0);
+ assert(tuple.get("myString").equals("b"));
+ assert(tuple.getDouble("count(*)") == 2);
+ assert(tuple.getDouble("sum") == 19);
+ assert(tuple.getDouble("min(field_i)") == 8);
+ assert(tuple.getDouble("max(field_i)") == 11);
+ assert(tuple.getDouble("avg(field_i)") == 9.5D);
+
+ tuple = tuples.get(1);
+ assert(tuple.get("myString").equals("a"));
+ assert(tuple.getDouble("count(*)") == 2);
+ assert(tuple.getDouble("sum") == 27);
+ assert(tuple.getDouble("min(field_i)") == 7);
+ assert(tuple.getDouble("max(field_i)") == 20);
+ assert(tuple.getDouble("avg(field_i)") == 13.5D);
+
+
params = new HashMap();
params.put(CommonParams.QT, "/sql");
params.put("stmt", "select str_s, count(*), sum(field_i), min(field_i), max(field_i), avg(field_i) from collection1 where (text='XXXX' AND NOT text='XXXX XXX') group by str_s order by str_s desc");
@@ -598,6 +675,44 @@ public class TestSQLHandler extends Abst
params = new HashMap();
params.put(CommonParams.QT, "/sql");
+ params.put("stmt", "select str_s as myString, count(*) as count, sum(field_i) as sum, min(field_i) as min, max(field_i) as max, avg(field_i) as avg from collection1 where (text='XXXX' AND NOT text='XXXX XXX') group by str_s order by str_s desc");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ //The sort by and order by match and no limit is applied. All the Tuples should be returned in
+ //this scenario.
+
+ assert(tuples.size() == 3);
+
+ tuple = tuples.get(0);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getDouble("count") == 4);
+ assert(tuple.getDouble("sum") == 180);
+ assert(tuple.getDouble("min") == 30);
+ assert(tuple.getDouble("max") == 60);
+ assert(tuple.getDouble("avg") == 45);
+
+ tuple = tuples.get(1);
+ assert(tuple.get("myString").equals("b"));
+ assert(tuple.getDouble("count") == 2);
+ assert(tuple.getDouble("sum") == 19);
+ assert(tuple.getDouble("min") == 8);
+ assert(tuple.getDouble("max") == 11);
+ assert(tuple.getDouble("avg") == 9.5D);
+
+ tuple = tuples.get(2);
+ assert(tuple.get("myString").equals("a"));
+ assert(tuple.getDouble("count") == 2);
+ assert(tuple.getDouble("sum") == 27);
+ assert(tuple.getDouble("min") == 7);
+ assert(tuple.getDouble("max") == 20);
+ assert(tuple.getDouble("avg") == 13.5D);
+
+
+
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
params.put("stmt", "select str_s, count(*), sum(field_i), min(field_i), max(field_i), avg(field_i) from collection1 where text='XXXX' group by str_s having sum(field_i) = 19");
solrStream = new SolrStream(jetty.url, params);
@@ -633,6 +748,25 @@ public class TestSQLHandler extends Abst
params = new HashMap();
params.put(CommonParams.QT, "/sql");
+ params.put("stmt", "select str_s as myString, count(*), sum(field_i) as sum, min(field_i), max(field_i), avg(field_i) from collection1 where text='XXXX' group by myString having ((sum = 19) AND (min(field_i) = 8))");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ //Only two results because of the limit.
+ assert(tuples.size() == 1);
+
+ tuple = tuples.get(0);
+ assert(tuple.get("myString").equals("b"));
+ assert(tuple.getDouble("count(*)") == 2);
+ assert(tuple.getDouble("sum") == 19);
+ assert(tuple.getDouble("min(field_i)") == 8);
+ assert(tuple.getDouble("max(field_i)") == 11);
+ assert(tuple.getDouble("avg(field_i)") == 9.5D);
+
+
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
params.put("stmt", "select str_s, count(*), sum(field_i), min(field_i), max(field_i), avg(field_i) from collection1 where text='XXXX' group by str_s having ((sum(field_i) = 19) AND (min(field_i) = 100))");
solrStream = new SolrStream(jetty.url, params);
@@ -740,6 +874,43 @@ public class TestSQLHandler extends Abst
assert(tuple.getLong("field_i") == 1);
+ //reverse the sort
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
+ params.put("aggregationMode", "facet");
+ params.put("stmt", "select distinct str_s as myString, field_i as myInt from collection1 order by str_s desc, myInt desc");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ assert(tuples.size() == 6);
+
+ tuple = tuples.get(0);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getLong("myInt") == 60);
+
+ tuple = tuples.get(1);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getLong("myInt") == 50);
+
+
+ tuple = tuples.get(2);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getLong("myInt") == 30);
+
+ tuple = tuples.get(3);
+ assert(tuple.get("myString").equals("b"));
+ assert(tuple.getLong("myInt") == 2);
+
+
+ tuple = tuples.get(4);
+ assert(tuple.get("myString").equals("a"));
+ assert(tuple.getLong("myInt") == 20);
+
+ tuple = tuples.get(5);
+ assert(tuple.get("myString").equals("a"));
+ assert(tuple.getLong("myInt") == 1);
+
//test with limit
params = new HashMap();
params.put(CommonParams.QT, "/sql");
@@ -915,6 +1086,42 @@ public class TestSQLHandler extends Abst
assert(tuple.getLong("field_i") == 1);
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
+ params.put("stmt", "select distinct str_s as myString, field_i from collection1 order by myString desc, field_i desc");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ assert(tuples.size() == 6);
+
+ tuple = tuples.get(0);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getLong("field_i") == 60);
+
+ tuple = tuples.get(1);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getLong("field_i") == 50);
+
+
+ tuple = tuples.get(2);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getLong("field_i") == 30);
+
+ tuple = tuples.get(3);
+ assert(tuple.get("myString").equals("b"));
+ assert(tuple.getLong("field_i") == 2);
+
+
+ tuple = tuples.get(4);
+ assert(tuple.get("myString").equals("a"));
+ assert(tuple.getLong("field_i") == 20);
+
+ tuple = tuples.get(5);
+ assert(tuple.get("myString").equals("a"));
+ assert(tuple.getLong("field_i") == 1);
+
+
//test with limit
params = new HashMap();
params.put(CommonParams.QT, "/sql");
@@ -1254,6 +1461,45 @@ public class TestSQLHandler extends Abst
assert(tuple.getDouble("max(field_i)") == 20);
assert(tuple.getDouble("avg(field_i)") == 13.5D);
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
+ params.put("aggregationMode", "facet");
+ params.put("stmt", "select str_s as myString, count(*), sum(field_i) as sum, min(field_i), max(field_i), avg(field_i) from collection1 where (text='XXXX' AND NOT text='XXXX XXX') group by myString order by myString desc");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ //The sort by and order by match and no limit is applied. All the Tuples should be returned in
+ //this scenario.
+
+ assert(tuples.size() == 3);
+
+ tuple = tuples.get(0);
+ assert(tuple.get("myString").equals("c"));
+ assert(tuple.getDouble("count(*)") == 4);
+ assert(tuple.getDouble("sum") == 180);
+ assert(tuple.getDouble("min(field_i)") == 30);
+ assert(tuple.getDouble("max(field_i)") == 60);
+ assert(tuple.getDouble("avg(field_i)") == 45);
+
+ tuple = tuples.get(1);
+ assert(tuple.get("myString").equals("b"));
+ assert(tuple.getDouble("count(*)") == 2);
+ assert(tuple.getDouble("sum") == 19);
+ assert(tuple.getDouble("min(field_i)") == 8);
+ assert(tuple.getDouble("max(field_i)") == 11);
+ assert(tuple.getDouble("avg(field_i)") == 9.5D);
+
+ tuple = tuples.get(2);
+ assert(tuple.get("myString").equals("a"));
+ assert(tuple.getDouble("count(*)") == 2);
+ assert(tuple.getDouble("sum") == 27);
+ assert(tuple.getDouble("min(field_i)") == 7);
+ assert(tuple.getDouble("max(field_i)") == 20);
+ assert(tuple.getDouble("avg(field_i)") == 13.5D);
+
+
+
params = new HashMap();
params.put(CommonParams.QT, "/sql");
@@ -1292,6 +1538,26 @@ public class TestSQLHandler extends Abst
assert(tuple.getDouble("max(field_i)") == 11);
assert(tuple.getDouble("avg(field_i)") == 9.5D);
+
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
+ params.put("aggregationMode", "facet");
+ params.put("stmt", "select str_s myString, count(*), sum(field_i) as sum, min(field_i), max(field_i), avg(field_i) from collection1 where text='XXXX' group by myString having ((sum = 19) AND (min(field_i) = 8))");
+
+ solrStream = new SolrStream(jetty.url, params);
+ tuples = getTuples(solrStream);
+
+ //Only two results because of the limit.
+ assert(tuples.size() == 1);
+
+ tuple = tuples.get(0);
+ assert(tuple.get("myString").equals("b"));
+ assert(tuple.getDouble("count(*)") == 2);
+ assert(tuple.getDouble("sum") == 19);
+ assert(tuple.getDouble("min(field_i)") == 8);
+ assert(tuple.getDouble("max(field_i)") == 11);
+ assert(tuple.getDouble("avg(field_i)") == 9.5D);
+
params = new HashMap();
params.put(CommonParams.QT, "/sql");
params.put("aggregationMode", "facet");
@@ -1516,6 +1782,45 @@ public class TestSQLHandler extends Abst
assertTrue(count.doubleValue() == 10);
+
+ params = new HashMap();
+ params.put(CommonParams.QT, "/sql");
+ params.put("stmt", "select count(*) as count, sum(a_i) as sum, min(a_i) as min, max(a_i) as max, avg(a_i) as avg, sum(a_f), min(a_f), max(a_f), avg(a_f) from collection1");
+
+ solrStream = new SolrStream(jetty.url, params);
+
+
+ tuples = getTuples(solrStream);
+
+ assert(tuples.size() == 1);
+
+ //Test Long and Double Sums
+
+ tuple = tuples.get(0);
+
+ sumi = tuple.getDouble("sum");
+ sumf = tuple.getDouble("sum(a_f)");
+ mini = tuple.getDouble("min");
+ minf = tuple.getDouble("min(a_f)");
+ maxi = tuple.getDouble("max");
+ maxf = tuple.getDouble("max(a_f)");
+ avgi = tuple.getDouble("avg");
+ avgf = tuple.getDouble("avg(a_f)");
+ count = tuple.getDouble("count");
+
+ assertTrue(sumi.longValue() == 70);
+ assertTrue(sumf.doubleValue() == 55.0D);
+ assertTrue(mini.doubleValue() == 0.0D);
+ assertTrue(minf.doubleValue() == 1.0D);
+ assertTrue(maxi.doubleValue() == 14.0D);
+ assertTrue(maxf.doubleValue() == 10.0D);
+ assertTrue(avgi.doubleValue() == 7.0D);
+ assertTrue(avgf.doubleValue() == 5.5D);
+ assertTrue(count.doubleValue() == 10);
+
+
+
+
// Test where clause hits
params = new HashMap();