/*
* Licensed to Crate under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership. Crate 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial
* agreement.
*/
package io.crate.operation.collect;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import io.crate.analyze.OrderBy;
import io.crate.analyze.WhereClause;
import io.crate.analyze.symbol.Literal;
import io.crate.analyze.symbol.Symbol;
import io.crate.data.Buckets;
import io.crate.data.Row;
import io.crate.data.Input;
import io.crate.operation.InputFactory;
import io.crate.operation.projectors.InputCondition;
import io.crate.operation.projectors.sorting.OrderingByPosition;
import io.crate.operation.reference.ReferenceResolver;
import io.crate.planner.node.dql.RoutedCollectPhase;
import io.crate.types.DataTypes;
import java.util.ArrayList;
import java.util.Collections;
public final class RowsTransformer {
public static Iterable<Row> toRowsIterable(InputFactory inputFactory,
ReferenceResolver<?> referenceResolver,
RoutedCollectPhase collectPhase,
Iterable<?> iterable) {
WhereClause whereClause = collectPhase.whereClause();
if (whereClause.noMatch()) {
return Collections.emptyList();
}
InputFactory.Context ctx = inputFactory.ctxForRefs(referenceResolver);
ctx.add(collectPhase.toCollect());
OrderBy orderBy = collectPhase.orderBy();
if (orderBy != null) {
for (Symbol symbol : orderBy.orderBySymbols()) {
ctx.add(symbol);
}
}
Input<Boolean> condition;
if (whereClause.hasQuery()) {
assert DataTypes.BOOLEAN.equals(whereClause.query().valueType()) :
"whereClause.query() must be of type " + DataTypes.BOOLEAN;
//noinspection unchecked whereClause().query() is a symbol of type boolean so it must become Input<Boolean>
condition = (Input<Boolean>) ctx.add(whereClause.query());
} else {
condition = Literal.BOOLEAN_TRUE;
}
@SuppressWarnings("unchecked")
Iterable<Row> rows = Iterables.filter(
Iterables.transform(iterable, new ValueAndInputRow<>(ctx.topLevelInputs(), ctx.expressions())),
InputCondition.asPredicate(condition));
if (orderBy == null) {
return rows;
}
return sortRows(Iterables.transform(rows, Row::materialize), collectPhase);
}
public static Iterable<Row> sortRows(Iterable<Object[]> rows, RoutedCollectPhase collectPhase) {
ArrayList<Object[]> objects = Lists.newArrayList(rows);
Ordering<Object[]> ordering = OrderingByPosition.arrayOrdering(collectPhase);
Collections.sort(objects, ordering.reverse());
return Iterables.transform(objects, Buckets.arrayToRowFunction());
}
}