You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kr...@apache.org on 2016/10/27 21:59:02 UTC
[2/2] lucene-solr:jira/solr-8593: Update Calcite rules
Update Calcite rules
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/073fecfa
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/073fecfa
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/073fecfa
Branch: refs/heads/jira/solr-8593
Commit: 073fecfa53943a0fd6368d19a3e0b764d6bfb4a7
Parents: e1ed290
Author: Kevin Risden <kr...@apache.org>
Authored: Thu Oct 27 16:58:56 2016 -0500
Committer: Kevin Risden <kr...@apache.org>
Committed: Thu Oct 27 16:58:56 2016 -0500
----------------------------------------------------------------------
.../apache/solr/handler/sql/SolrAggregate.java | 24 ++-
.../apache/solr/handler/sql/SolrEnumerator.java | 51 +++++-
.../apache/solr/handler/sql/SolrProject.java | 6 +-
.../org/apache/solr/handler/sql/SolrRel.java | 38 ++---
.../org/apache/solr/handler/sql/SolrRules.java | 12 +-
.../org/apache/solr/handler/sql/SolrSchema.java | 2 +-
.../org/apache/solr/handler/sql/SolrSort.java | 6 +-
.../org/apache/solr/handler/sql/SolrTable.java | 160 ++++++++++---------
.../handler/sql/SolrToEnumerableConverter.java | 36 ++++-
9 files changed, 200 insertions(+), 135 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrAggregate.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrAggregate.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrAggregate.java
index 02b50c5..f913585 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrAggregate.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrAggregate.java
@@ -65,27 +65,21 @@ class SolrAggregate extends Aggregate implements SolrRel {
implementor.visitChild(0, getInput());
final List<String> inNames = SolrRules.solrFieldNames(getInput().getRowType());
- final List<String> outNames = SolrRules.solrFieldNames(getRowType());
- Map<String, String> fieldMappings = new HashMap<>();
- for(AggregateCall aggCall : aggCalls) {
+ for(Pair<AggregateCall, String> namedAggCall : getNamedAggCalls()) {
+ AggregateCall aggCall = namedAggCall.getKey();
Pair<String, String> metric = toSolrMetric(implementor, aggCall, inNames);
- implementor.addMetric(metric);
- fieldMappings.put(aggCall.getName(), metric.getKey().toLowerCase(Locale.ROOT) + "(" + metric.getValue() + ")");
+ implementor.addMetricPair(namedAggCall.getValue(), metric.getKey(), metric.getValue());
+ if(aggCall.getName() == null) {
+ implementor.addFieldMapping(namedAggCall.getValue(),
+ aggCall.getAggregation().getName() + "(" + inNames.get(aggCall.getArgList().get(0)) + ")");
+ }
}
- List<String> buckets = new ArrayList<>();
- for(int group : groupSet) {
+ for(int group : getGroupSet()) {
String inName = inNames.get(group);
- String name = implementor.fieldMappings.getOrDefault(inName, inName);
- buckets.add(name);
- if(!fieldMappings.containsKey(name)) {
- fieldMappings.put(name, name);
- }
+ implementor.addBucket(inName);
}
-
- implementor.addBuckets(buckets);
- implementor.addFieldMappings(fieldMappings);
}
private Pair<String, String> toSolrMetric(Implementor implementor, AggregateCall aggCall, List<String> inNames) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrEnumerator.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrEnumerator.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrEnumerator.java
index b9d0cec..1714e67 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrEnumerator.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrEnumerator.java
@@ -19,14 +19,19 @@ package org.apache.solr.handler.sql;
import org.apache.calcite.linq4j.Enumerator;
import org.apache.solr.client.solrj.io.Tuple;
import org.apache.solr.client.solrj.io.stream.TupleStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
+import java.util.Map;
/** Enumerator that reads from a Solr collection. */
class SolrEnumerator implements Enumerator<Object> {
+ private static final Logger logger = LoggerFactory.getLogger(SolrEnumerator.class);
+
private final TupleStream tupleStream;
- private final List<String> fields;
+ private final List<Map.Entry<String, Class>> fields;
private Tuple current;
/** Creates a SolrEnumerator.
@@ -34,7 +39,7 @@ class SolrEnumerator implements Enumerator<Object> {
* @param tupleStream Solr TupleStream
* @param fields Fields to get from each Tuple
*/
- SolrEnumerator(TupleStream tupleStream, List<String> fields) {
+ SolrEnumerator(TupleStream tupleStream, List<Map.Entry<String, Class>> fields) {
this.tupleStream = tupleStream;
try {
this.tupleStream.open();
@@ -51,18 +56,54 @@ class SolrEnumerator implements Enumerator<Object> {
*/
public Object current() {
if (fields.size() == 1) {
- return current.get(fields.get(0));
+ return this.getter(current, fields.get(0));
} else {
// Build an array with all fields in this row
Object[] row = new Object[fields.size()];
for (int i = 0; i < fields.size(); i++) {
- row[i] = current.get(fields.get(i));
+ row[i] = this.getter(current, fields.get(i));
}
return row;
}
}
+ private Object getter(Tuple tuple, Map.Entry<String, Class> field) {
+ Object val = tuple.get(field.getKey());
+ Class clazz = field.getValue();
+
+ if(clazz.equals(Double.class)) {
+ return val == null ? 0D : val;
+ }
+
+ if(clazz.equals(Long.class)) {
+ if(val == null) {
+ return 0L;
+ }
+ if(val instanceof Double) {
+ return this.getRealVal(val);
+ }
+ return val;
+ }
+
+ return val;
+ }
+
+ private Object getRealVal(Object val) {
+ // Check if Double is really a Long
+ if(val instanceof Double) {
+ Double doubleVal = (double) val;
+ //make sure that double has no decimals and fits within Long
+ if(doubleVal % 1 == 0 && doubleVal >= Long.MIN_VALUE && doubleVal <= Long.MAX_VALUE) {
+ return doubleVal.longValue();
+ }
+ return doubleVal;
+ }
+
+ // Wasn't a double so just return original Object
+ return val;
+ }
+
public boolean moveNext() {
try {
Tuple tuple = this.tupleStream.read();
@@ -73,7 +114,7 @@ class SolrEnumerator implements Enumerator<Object> {
return true;
}
} catch (IOException e) {
- e.printStackTrace();
+ logger.error("IOException", e);
return false;
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrProject.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrProject.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrProject.java
index fb7e5e8..c4217f2 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrProject.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrProject.java
@@ -28,9 +28,7 @@ import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.Pair;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* Implementation of {@link org.apache.calcite.rel.core.Project} relational expression in Solr.
@@ -57,12 +55,10 @@ class SolrProject extends Project implements SolrRel {
implementor.visitChild(0, getInput());
final SolrRules.RexToSolrTranslator translator = new SolrRules.RexToSolrTranslator(
(JavaTypeFactory) getCluster().getTypeFactory(), SolrRules.solrFieldNames(getInput().getRowType()));
- final Map<String, String> fieldMappings = new HashMap<>();
for (Pair<RexNode, String> pair : getNamedProjects()) {
final String name = pair.right;
final String expr = pair.left.accept(translator);
- fieldMappings.put(name, expr);
+ implementor.addFieldMapping(name, expr);
}
- implementor.addFieldMappings(fieldMappings);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrRel.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrRel.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrRel.java
index 5a2ab6f..ce67a30 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrRel.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrRel.java
@@ -21,10 +21,7 @@ import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.util.Pair;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* Relational expression that uses Solr calling convention.
@@ -40,36 +37,41 @@ interface SolrRel extends RelNode {
final Map<String, String> fieldMappings = new HashMap<>();
String query = null;
String limitValue = null;
- final List<String> order = new ArrayList<>();
+ final List<Pair<String, String>> orders = new ArrayList<>();
final List<String> buckets = new ArrayList<>();
final List<Pair<String, String>> metricPairs = new ArrayList<>();
RelOptTable table;
SolrTable solrTable;
- void addFieldMappings(Map<String, String> fieldMappings) {
- this.fieldMappings.putAll(fieldMappings);
+ void addFieldMapping(String key, String val) {
+ if(key != null && !fieldMappings.containsKey(key)) {
+ this.fieldMappings.put(key, val);
+ }
}
void addQuery(String query) {
this.query = query;
}
- void addOrder(List<String> order) {
- for(String orderItem : order) {
- String[] orderParts = orderItem.split(" ", 2);
- String fieldName = orderParts[0];
- String direction = orderParts[1];
- this.order.add(this.fieldMappings.getOrDefault(fieldName, fieldName) + " " + direction);
- }
+ void addOrder(String column, String direction) {
+ column = this.fieldMappings.getOrDefault(column, column);
+ this.orders.add(new Pair<>(column, direction));
}
- void addBuckets(List<String> buckets) {
- this.buckets.addAll(buckets);
+ void addBucket(String bucket) {
+ bucket = this.fieldMappings.getOrDefault(bucket, bucket);
+ this.buckets.add(bucket);
}
- void addMetric(Pair<String, String> metricPair) {
- this.metricPairs.add(metricPair);
+ void addMetricPair(String outName, String metric, String column) {
+ column = this.fieldMappings.getOrDefault(column, column);
+ this.metricPairs.add(new Pair<>(metric, column));
+
+ String metricIdentifier = metric + "(" + column + ")";
+ if(outName != null) {
+ this.addFieldMapping(outName, metricIdentifier.toLowerCase(Locale.ROOT));
+ }
}
void setLimit(String limit) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java
index 7bc142b..7d1aa59 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java
@@ -65,7 +65,7 @@ class SolrRules {
public int size() {
return rowType.getFieldCount();
}
- });
+ }, true);
}
/** Translator from {@link RexNode} to strings in Solr's expression language. */
@@ -127,9 +127,11 @@ class SolrRules {
abstract public RelNode convert(RelNode rel);
+ /**
+ * @see ConverterRule
+ */
@Override
public void onMatch(RelOptRuleCall call) {
- /** @see ConverterRule */
RelNode rel = call.rel(0);
if (rel.getTraitSet().contains(Convention.NONE)) {
final RelNode converted = convert(rel);
@@ -218,10 +220,14 @@ class SolrRules {
* Rule to convert an {@link LogicalAggregate} to an {@link SolrAggregate}.
*/
private static class SolrAggregateRule extends SolrConverterRule {
+ private static final Predicate<RelNode> AGGREGATE_PREDICTE = relNode ->
+ Aggregate.IS_SIMPLE.apply(((LogicalAggregate)relNode));// &&
+// !((LogicalAggregate)relNode).containsDistinctCall();
+
private static final RelOptRule AGGREGATE_RULE = new SolrAggregateRule();
private SolrAggregateRule() {
- super(LogicalAggregate.class, relNode -> Aggregate.IS_SIMPLE.apply(((LogicalAggregate)relNode)), "SolrAggregateRule");
+ super(LogicalAggregate.class, AGGREGATE_PREDICTE, "SolrAggregateRule");
}
public RelNode convert(RelNode rel) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java
index 1b94e4c..8c3eaa9 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrSchema.java
@@ -46,7 +46,7 @@ class SolrSchema extends AbstractSchema {
String zk = this.properties.getProperty("zk");
try(CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zk).build()) {
cloudSolrClient.connect();
- Set<String> collections = cloudSolrClient.getZkStateReader().getClusterState().getCollections();
+ Set<String> collections = cloudSolrClient.getZkStateReader().getClusterState().getCollectionsMap().keySet();
final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();
for (String collection : collections) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrSort.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrSort.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrSort.java
index 4f6cd4a..7deabeb 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrSort.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrSort.java
@@ -29,7 +29,6 @@ import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -58,7 +57,6 @@ class SolrSort extends Sort implements SolrRel {
implementor.visitChild(0, getInput());
List<RelFieldCollation> sortCollations = collation.getFieldCollations();
- List<String> fieldOrder = new ArrayList<>();
if (!sortCollations.isEmpty()) {
// Construct a series of order clauses from the desired collation
final List<RelDataTypeField> fields = getRowType().getFieldList();
@@ -68,10 +66,8 @@ class SolrSort extends Sort implements SolrRel {
if (fieldCollation.getDirection().equals(RelFieldCollation.Direction.DESCENDING)) {
direction = "desc";
}
- fieldOrder.add(name + " " + direction);
+ implementor.addOrder(name, direction);
}
-
- implementor.addOrder(fieldOrder);
}
if(fetch != null) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrTable.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrTable.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrTable.java
index 6884658..6e4631c 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrTable.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrTable.java
@@ -36,18 +36,18 @@ import org.apache.solr.client.solrj.io.stream.*;
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
import org.apache.solr.client.solrj.io.stream.metrics.*;
import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.update.VersionInfo;
+import org.apache.solr.common.params.ModifiableSolrParams;
import java.io.IOException;
import java.util.*;
+import java.util.stream.Collectors;
/**
* Table based on a Solr collection
*/
class SolrTable extends AbstractQueryableTable implements TranslatableTable {
private static final String DEFAULT_QUERY = "*:*";
- private static final String DEFAULT_VERSION_FIELD = VersionInfo.VERSION_FIELD;
- private static final String DEFAULT_SCORE_FIELD = "score";
+ private static final String DEFAULT_VERSION_FIELD = "_version_";
private final String collection;
private final SolrSchema schema;
@@ -82,64 +82,81 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
* @param query A string for the query
* @return Enumerator of results
*/
- private Enumerable<Object> query(final Properties properties, final List<String> fields,
- final String query, final List<String> order, final List<String> buckets,
+ private Enumerable<Object> query(final Properties properties, final List<Map.Entry<String, Class>> fields,
+ final String query, final List<Pair<String, String>> orders, final List<String> buckets,
final List<Pair<String, String>> metricPairs, final String limit) {
// SolrParams should be a ModifiableParams instead of a map
- Map<String, String> solrParams = new HashMap<>();
- solrParams.put(CommonParams.OMIT_HEADER, "true");
+ ModifiableSolrParams solrParams = new ModifiableSolrParams();
+ solrParams.add(CommonParams.OMIT_HEADER, "true");
if (query == null) {
- solrParams.put(CommonParams.Q, DEFAULT_QUERY);
+ solrParams.add(CommonParams.Q, DEFAULT_QUERY);
} else {
- solrParams.put(CommonParams.Q, DEFAULT_QUERY + " AND " + query);
+ solrParams.add(CommonParams.Q, DEFAULT_QUERY + " AND " + query);
}
// List<String> doesn't have add so must make a new ArrayList
- List<String> fieldsList = new ArrayList<>(fields);
- List<String> orderList = new ArrayList<>(order);
-
+ List<String> fieldsList = new ArrayList<>(fields.size());
+ fieldsList.addAll(fields.stream().map(Map.Entry::getKey).collect(Collectors.toList()));
+ List<Pair<String, String>> ordersList = new ArrayList<>(orders);
List<Metric> metrics = buildMetrics(metricPairs);
+ List<Bucket> bucketsList = buckets.stream().map(Bucket::new).collect(Collectors.toList());
+
+ for(int i = buckets.size()-1; i >= 0; i--) {
+ ordersList.add(0, new Pair<>(buckets.get(i), "asc"));
+ }
+
+ for(Metric metric : metrics) {
+ String metricIdentifier = metric.getIdentifier();
- if (!metrics.isEmpty()) {
- for(String bucket : buckets) {
- orderList.add(bucket + " desc");
+ List<Pair<String, String>> newOrders= new ArrayList<>();
+ for(Pair<String, String> order : ordersList) {
+ String column = order.getKey();
+ if(!column.startsWith(metricIdentifier)) {
+ newOrders.add(order);
+ }
}
+ ordersList = newOrders;
- for(Metric metric : metrics) {
- List<String> newOrderList = new ArrayList<>();
- for(String orderItem : orderList) {
- if(!orderItem.startsWith(metric.getIdentifier())) {
- newOrderList.add(orderItem);
- }
+ if(fieldsList.contains(metricIdentifier)) {
+ fieldsList.remove(metricIdentifier);
+ }
+
+ for(String column : metric.getColumns()) {
+ if (!fieldsList.contains(column)) {
+ fieldsList.add(column);
}
- orderList = newOrderList;
- for(String column : metric.getColumns()) {
- if (!fieldsList.contains(column)) {
- fieldsList.add(column);
- }
+ Pair<String, String> order = new Pair<>(column, "asc");
+ if(!ordersList.contains(order)) {
+ ordersList.add(order);
}
}
}
- if (orderList.isEmpty()) {
- orderList.add(DEFAULT_VERSION_FIELD + " desc");
+ ordersList.add(new Pair<>(DEFAULT_VERSION_FIELD, "desc"));
- // Make sure the default sort field is in the field list
- if (!fieldsList.contains(DEFAULT_VERSION_FIELD)) {
- fieldsList.add(DEFAULT_VERSION_FIELD);
- }
+ // Make sure the default sort field is in the field list
+ if (!fieldsList.contains(DEFAULT_VERSION_FIELD)) {
+ fieldsList.add(DEFAULT_VERSION_FIELD);
}
- if(!orderList.isEmpty()) {
- solrParams.put(CommonParams.SORT, String.join(",", orderList));
+ if(!ordersList.isEmpty()) {
+ List<String> orderList = new ArrayList<>(ordersList.size());
+ for(Pair<String, String> order : ordersList) {
+ String column = order.getKey();
+ if(!fieldsList.contains(column)) {
+ fieldsList.add(column);
+ }
+ orderList.add(column + " " + order.getValue());
+ }
+ solrParams.add(CommonParams.SORT, String.join(",", orderList));
}
if (fieldsList.isEmpty()) {
- solrParams.put(CommonParams.FL, "*");
+ solrParams.add(CommonParams.FL, "*");
} else {
- solrParams.put(CommonParams.FL, String.join(",", fieldsList));
+ solrParams.add(CommonParams.FL, String.join(",", fieldsList));
}
TupleStream tupleStream;
@@ -147,33 +164,24 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
try {
if (metrics.isEmpty()) {
if (limit == null) {
- solrParams.put(CommonParams.QT, "/export");
+ solrParams.add(CommonParams.QT, "/export");
tupleStream = new CloudSolrStream(zk, collection, solrParams);
} else {
- solrParams.put(CommonParams.ROWS, limit);
+ solrParams.add(CommonParams.ROWS, limit);
tupleStream = new LimitStream(new CloudSolrStream(zk, collection, solrParams), Integer.parseInt(limit));
}
} else {
Metric[] metricsArray = metrics.toArray(new Metric[metrics.size()]);
- if(buckets.isEmpty()) {
+ if(bucketsList.isEmpty()) {
solrParams.remove(CommonParams.FL);
solrParams.remove(CommonParams.SORT);
tupleStream = new StatsStream(zk, collection, solrParams, metricsArray);
} else {
- List<Bucket> bucketsList = new ArrayList<>();
- for(String bucket : buckets) {
- bucketsList.add(new Bucket(bucket));
- }
-
- solrParams.put(CommonParams.QT, "/export");
- for(Metric metric : metrics) {
- fieldsList.remove(metric.getIdentifier());
- }
- solrParams.put(CommonParams.FL, String.join(",", fieldsList));
+ solrParams.add(CommonParams.QT, "/export");
tupleStream = new CloudSolrStream(zk, collection, solrParams);
tupleStream = new RollupStream(tupleStream, bucketsList.toArray(new Bucket[bucketsList.size()]), metricsArray);
- String sortDirection = getSortDirection(orderList);
+ String sortDirection = getSortDirection(ordersList);
int numWorkers = Integer.parseInt(properties.getProperty("numWorkers", "1"));
if(numWorkers > 1) {
@@ -198,9 +206,9 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
tupleStream = parallelStream;
}
- if (!sortsEqual(bucketsList, sortDirection, orderList)) {
+ if (!sortsEqual(bucketsList, sortDirection, ordersList)) {
int limitVal = limit == null ? 100 : Integer.parseInt(limit);
- StreamComparator comp = getComp(orderList);
+ StreamComparator comp = getComp(ordersList);
//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.
@@ -209,7 +217,7 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
// Sort is the same as the same as the underlying stream
// Only need to limit the result, not Rank the result
if (limit != null) {
- solrParams.put(CommonParams.ROWS, limit);
+ solrParams.add(CommonParams.ROWS, limit);
tupleStream = new LimitStream(new CloudSolrStream(zk, collection, solrParams), Integer.parseInt(limit));
}
}
@@ -244,20 +252,20 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
}
}
- private boolean sortsEqual(List<Bucket> buckets, String direction, List<String> orderList) {
- if(buckets.size() != orderList.size()) {
+ private boolean sortsEqual(List<Bucket> buckets, String direction, List<Pair<String, String>> orders) {
+ if(buckets.size() != orders.size()) {
return false;
}
for(int i=0; i< buckets.size(); i++) {
Bucket bucket = buckets.get(i);
- String orderItem = orderList.get(i);
- if(!bucket.toString().equals(getSortField(orderItem))) {
+ Pair<String, String> order = orders.get(i);
+ if(!bucket.toString().equals(getSortField(order))) {
return false;
}
- if(!getSortDirection(orderItem).equalsIgnoreCase(direction)) {
+ if(!getSortDirection(order).equalsIgnoreCase(direction)) {
return false;
}
}
@@ -266,32 +274,30 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
}
- private String getSortDirection(List<String> orderList) {
- for(String orderItem : orderList) {
- return getSortDirection(orderItem);
+ private String getSortDirection(List<Pair<String, String>> orders) {
+ for(Pair<String, String> order : orders) {
+ return getSortDirection(order);
}
return "asc";
}
- private String getSortField(String orderItem) {
- String[] orderParts = orderItem.split(" ", 2);
- return orderParts[0];
+ private String getSortField(Pair<String, String> order) {
+ return order.getKey();
}
- private String getSortDirection(String orderItem) {
- String[] orderParts = orderItem.split(" ", 2);
- String direction = orderParts[1];
+ private String getSortDirection(Pair<String, String> order) {
+ String direction = order.getValue();
return direction == null ? "asc" : direction;
}
- private StreamComparator getComp(List<String> orderList) {
- FieldComparator[] comps = new FieldComparator[orderList.size()];
- for(int i = 0; i < orderList.size(); i++) {
- String orderItem = orderList.get(i);
- String direction = getSortDirection(orderItem);
+ private StreamComparator getComp(List<Pair<String, String>> orders) {
+ FieldComparator[] comps = new FieldComparator[orders.size()];
+ for(int i = 0; i < orders.size(); i++) {
+ Pair<String, String> order = orders.get(i);
+ String direction = getSortDirection(order);
ComparatorOrder comparatorOrder = ComparatorOrder.fromString(direction);
- String sortKey = getSortField(orderItem);
+ String sortKey = getSortField(order);
comps[i] = new FieldComparator(sortKey, comparatorOrder);
}
@@ -304,9 +310,7 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
private List<Metric> buildMetrics(List<Pair<String, String>> metricPairs) {
List<Metric> metrics = new ArrayList<>(metricPairs.size());
- for(Pair<String, String> metricPair : metricPairs) {
- metrics.add(getMetric(metricPair));
- }
+ metrics.addAll(metricPairs.stream().map(this::getMetric).collect(Collectors.toList()));
return metrics;
}
@@ -362,8 +366,8 @@ class SolrTable extends AbstractQueryableTable implements TranslatableTable {
* @see SolrMethod#SOLR_QUERYABLE_QUERY
*/
@SuppressWarnings("UnusedDeclaration")
- public Enumerable<Object> query(List<String> fields, String query, List<String> order, List<String> buckets,
- List<Pair<String, String>> metricPairs, String limit) {
+ public Enumerable<Object> query(List<Map.Entry<String, Class>> fields, String query, List<Pair<String, String>> order,
+ List<String> buckets, List<Pair<String, String>> metricPairs, String limit) {
return getTable().query(getProperties(), fields, query, order, buckets, metricPairs, limit);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/073fecfa/solr/core/src/java/org/apache/solr/handler/sql/SolrToEnumerableConverter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrToEnumerableConverter.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrToEnumerableConverter.java
index e6aea05..6737977 100644
--- a/solr/core/src/java/org/apache/solr/handler/sql/SolrToEnumerableConverter.java
+++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrToEnumerableConverter.java
@@ -31,6 +31,7 @@ import org.apache.calcite.runtime.Hook;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.Pair;
+import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -61,15 +62,27 @@ class SolrToEnumerableConverter extends ConverterImpl implements EnumerableRel {
final RelDataType rowType = getRowType();
final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), rowType, pref.prefer(JavaRowFormat.ARRAY));
final Expression table = list.append("table", solrImplementor.table.getExpression(SolrTable.SolrQueryable.class));
- final Expression fields = list.append("fields",
- constantArrayList(generateFields(SolrRules.solrFieldNames(rowType), solrImplementor.fieldMappings), String.class));
+ final Expression fields =
+ list.append("fields",
+ constantArrayList(
+ Pair.zip(generateFields(SolrRules.solrFieldNames(rowType), solrImplementor.fieldMappings),
+ new AbstractList<Class>() {
+ @Override public Class get(int index) {
+ return physType.fieldClass(index);
+ }
+
+ @Override public int size() {
+ return rowType.getFieldCount();
+ }
+ }),
+ Pair.class));
final Expression query = list.append("query", Expressions.constant(solrImplementor.query, String.class));
- final Expression order = list.append("order", constantArrayList(solrImplementor.order, String.class));
+ final Expression orders = list.append("orders", constantArrayList(solrImplementor.orders, Pair.class));
final Expression buckets = list.append("buckets", constantArrayList(solrImplementor.buckets, String.class));
final Expression metricPairs = list.append("metricPairs", constantArrayList(solrImplementor.metricPairs, Pair.class));
final Expression limit = list.append("limit", Expressions.constant(solrImplementor.limitValue));
Expression enumerable = list.append("enumerable", Expressions.call(table, SolrMethod.SOLR_QUERYABLE_QUERY.method,
- fields, query, order, buckets, metricPairs, limit));
+ fields, query, orders, buckets, metricPairs, limit));
Hook.QUERY_PLAN.run(query);
list.add(Expressions.return_(null, enumerable));
return implementor.result(physType, list.toBlock());
@@ -81,12 +94,25 @@ class SolrToEnumerableConverter extends ConverterImpl implements EnumerableRel {
} else {
List<String> fields = new ArrayList<>();
for(String field : queryFields) {
- fields.add(fieldMappings.getOrDefault(field, field));
+ fields.add(getField(fieldMappings, field));
}
return fields;
}
}
+ private String getField(Map<String, String> fieldMappings, String field) {
+ String retField = field;
+ while(fieldMappings.containsKey(field)) {
+ field = fieldMappings.getOrDefault(field, retField);
+ if(retField.equals(field)) {
+ break;
+ } else {
+ retField = field;
+ }
+ }
+ return retField;
+ }
+
/**
* E.g. {@code constantArrayList("x", "y")} returns
* "Arrays.asList('x', 'y')".