use of org.apache.phoenix.expression.OrderByExpression in project phoenix by apache.
the class ScanRegionObserver method serializeIntoScan.
public static void serializeIntoScan(Scan scan, int thresholdBytes, int limit, List<OrderByExpression> orderByExpressions, int estimatedRowSize) {
// TODO: size?
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
DataOutputStream output = new DataOutputStream(stream);
WritableUtils.writeVInt(output, thresholdBytes);
WritableUtils.writeVInt(output, limit);
WritableUtils.writeVInt(output, estimatedRowSize);
WritableUtils.writeVInt(output, orderByExpressions.size());
for (OrderByExpression orderingCol : orderByExpressions) {
orderingCol.write(output);
}
scan.setAttribute(BaseScannerRegionObserver.TOPN, stream.toByteArray());
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
stream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
use of org.apache.phoenix.expression.OrderByExpression in project phoenix by apache.
the class NonAggregateRegionScannerFactory method deserializeFromScan.
private static OrderedResultIterator deserializeFromScan(Scan scan, RegionScanner s) {
byte[] topN = scan.getAttribute(BaseScannerRegionObserver.TOPN);
if (topN == null) {
return null;
}
// TODO: size?
ByteArrayInputStream stream = new ByteArrayInputStream(topN);
try {
DataInputStream input = new DataInputStream(stream);
int thresholdBytes = WritableUtils.readVInt(input);
int limit = WritableUtils.readVInt(input);
int estimatedRowSize = WritableUtils.readVInt(input);
int size = WritableUtils.readVInt(input);
List<OrderByExpression> orderByExpressions = Lists.newArrayListWithExpectedSize(size);
for (int i = 0; i < size; i++) {
OrderByExpression orderByExpression = new OrderByExpression();
orderByExpression.readFields(input);
orderByExpressions.add(orderByExpression);
}
PTable.QualifierEncodingScheme encodingScheme = EncodedColumnsUtil.getQualifierEncodingScheme(scan);
ResultIterator inner = new RegionScannerResultIterator(s, EncodedColumnsUtil.getMinMaxQualifiersFromScan(scan), encodingScheme);
return new OrderedResultIterator(inner, orderByExpressions, thresholdBytes, limit >= 0 ? limit : null, null, estimatedRowSize);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
stream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
use of org.apache.phoenix.expression.OrderByExpression in project phoenix by apache.
the class MergeSortTopNResultIterator method compare.
@Override
protected int compare(Tuple t1, Tuple t2) {
for (int i = 0; i < orderByColumns.size(); i++) {
OrderByExpression order = orderByColumns.get(i);
Expression orderExpr = order.getExpression();
boolean isNull1 = !orderExpr.evaluate(t1, ptr1) || ptr1.getLength() == 0;
boolean isNull2 = !orderExpr.evaluate(t2, ptr2) || ptr2.getLength() == 0;
if (isNull1 && isNull2) {
continue;
} else if (isNull1) {
return order.isNullsLast() ? 1 : -1;
} else if (isNull2) {
return order.isNullsLast() ? -1 : 1;
}
int cmp = ptr1.compareTo(ptr2);
if (cmp == 0) {
continue;
}
return order.isAscending() ? cmp : -cmp;
}
return 0;
}
use of org.apache.phoenix.expression.OrderByExpression in project phoenix by apache.
the class OrderByCompiler method compile.
/**
* Gets a list of columns in the ORDER BY clause
* @param context the query context for tracking various states
* associated with the given select statement
* @param statement TODO
* @param groupBy the list of columns in the GROUP BY clause
* @param limit the row limit or null if no limit
* @return the compiled ORDER BY clause
* @throws SQLException
*/
public static OrderBy compile(StatementContext context, SelectStatement statement, GroupBy groupBy, Integer limit, Integer offset, RowProjector rowProjector, TupleProjector tupleProjector, boolean isInRowKeyOrder) throws SQLException {
List<OrderByNode> orderByNodes = statement.getOrderBy();
if (orderByNodes.isEmpty()) {
return OrderBy.EMPTY_ORDER_BY;
}
// for ungroupedAggregates as GROUP BY expression, check against an empty group by
ExpressionCompiler compiler;
if (groupBy.isUngroupedAggregate()) {
compiler = new ExpressionCompiler(context, GroupBy.EMPTY_GROUP_BY) {
@Override
protected Expression addExpression(Expression expression) {
return expression;
}
@Override
protected void addColumn(PColumn column) {
}
};
} else {
compiler = new ExpressionCompiler(context, groupBy);
}
// accumulate columns in ORDER BY
OrderPreservingTracker tracker = new OrderPreservingTracker(context, groupBy, Ordering.ORDERED, orderByNodes.size(), tupleProjector);
LinkedHashSet<OrderByExpression> orderByExpressions = Sets.newLinkedHashSetWithExpectedSize(orderByNodes.size());
for (OrderByNode node : orderByNodes) {
ParseNode parseNode = node.getNode();
Expression expression = null;
if (parseNode instanceof LiteralParseNode && ((LiteralParseNode) parseNode).getType() == PInteger.INSTANCE) {
Integer index = (Integer) ((LiteralParseNode) parseNode).getValue();
int size = rowProjector.getColumnProjectors().size();
if (index > size || index <= 0) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.PARAM_INDEX_OUT_OF_BOUND).build().buildException();
}
expression = rowProjector.getColumnProjector(index - 1).getExpression();
} else {
expression = node.getNode().accept(compiler);
// Detect mix of aggregate and non aggregates (i.e. ORDER BY txns, SUM(txns)
if (!expression.isStateless() && !compiler.isAggregate()) {
if (statement.isAggregate() || statement.isDistinct()) {
// Detect ORDER BY not in SELECT DISTINCT: SELECT DISTINCT count(*) FROM t ORDER BY x
if (statement.isDistinct()) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.ORDER_BY_NOT_IN_SELECT_DISTINCT).setMessage(expression.toString()).build().buildException();
}
ExpressionCompiler.throwNonAggExpressionInAggException(expression.toString());
}
}
}
if (!expression.isStateless()) {
boolean isAscending = node.isAscending();
boolean isNullsLast = node.isNullsLast();
tracker.track(expression, isAscending ? SortOrder.ASC : SortOrder.DESC, isNullsLast);
// since this is the order they actually are in.
if (expression.getSortOrder() == SortOrder.DESC) {
isAscending = !isAscending;
}
OrderByExpression orderByExpression = new OrderByExpression(expression, isNullsLast, isAscending);
orderByExpressions.add(orderByExpression);
}
compiler.reset();
}
// we can remove ORDER BY clauses in case of only COUNT(DISTINCT...) clauses
if (orderByExpressions.isEmpty() || groupBy.isUngroupedAggregate()) {
return OrderBy.EMPTY_ORDER_BY;
}
// If we're ordering by the order returned by the scan, we don't need an order by
if (isInRowKeyOrder && tracker.isOrderPreserving()) {
if (tracker.isReverse()) {
// REV_ROW_KEY_ORDER_BY scan would not take effect for a projected table, so don't return it for such table types.
if (context.getConnection().getQueryServices().getProps().getBoolean(QueryServices.USE_REVERSE_SCAN_ATTRIB, QueryServicesOptions.DEFAULT_USE_REVERSE_SCAN) && !context.getScanRanges().useSkipScanFilter() && context.getCurrentTable().getTable().getType() != PTableType.PROJECTED && context.getCurrentTable().getTable().getType() != PTableType.SUBQUERY) {
return OrderBy.REV_ROW_KEY_ORDER_BY;
}
} else {
return OrderBy.FWD_ROW_KEY_ORDER_BY;
}
}
return new OrderBy(Lists.newArrayList(orderByExpressions.iterator()));
}
use of org.apache.phoenix.expression.OrderByExpression in project phoenix by apache.
the class ClientAggregatePlan method iterator.
@Override
public ResultIterator iterator(ParallelScanGrouper scanGrouper, Scan scan) throws SQLException {
ResultIterator iterator = delegate.iterator(scanGrouper, scan);
if (where != null) {
iterator = new FilterResultIterator(iterator, where);
}
AggregatingResultIterator aggResultIterator;
if (groupBy.isEmpty()) {
aggResultIterator = new ClientUngroupedAggregatingResultIterator(LookAheadResultIterator.wrap(iterator), serverAggregators);
aggResultIterator = new UngroupedAggregatingResultIterator(LookAheadResultIterator.wrap(aggResultIterator), clientAggregators);
} else {
if (!groupBy.isOrderPreserving()) {
int thresholdBytes = context.getConnection().getQueryServices().getProps().getInt(QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);
List<Expression> keyExpressions = groupBy.getKeyExpressions();
List<OrderByExpression> keyExpressionOrderBy = Lists.newArrayListWithExpectedSize(keyExpressions.size());
for (Expression keyExpression : keyExpressions) {
keyExpressionOrderBy.add(new OrderByExpression(keyExpression, false, true));
}
iterator = new OrderedResultIterator(iterator, keyExpressionOrderBy, thresholdBytes, null, null, projector.getEstimatedRowByteSize());
}
aggResultIterator = new ClientGroupedAggregatingResultIterator(LookAheadResultIterator.wrap(iterator), serverAggregators, groupBy.getKeyExpressions());
aggResultIterator = new GroupedAggregatingResultIterator(LookAheadResultIterator.wrap(aggResultIterator), clientAggregators);
}
if (having != null) {
aggResultIterator = new FilterAggregatingResultIterator(aggResultIterator, having);
}
if (statement.isDistinct() && statement.isAggregate()) {
// Dedup on client if select distinct and aggregation
aggResultIterator = new DistinctAggregatingResultIterator(aggResultIterator, getProjector());
}
ResultIterator resultScanner = aggResultIterator;
if (orderBy.getOrderByExpressions().isEmpty()) {
if (offset != null) {
resultScanner = new OffsetResultIterator(resultScanner, offset);
}
if (limit != null) {
resultScanner = new LimitingResultIterator(resultScanner, limit);
}
} else {
int thresholdBytes = context.getConnection().getQueryServices().getProps().getInt(QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);
resultScanner = new OrderedAggregatingResultIterator(aggResultIterator, orderBy.getOrderByExpressions(), thresholdBytes, limit, offset);
}
if (context.getSequenceManager().getSequenceCount() > 0) {
resultScanner = new SequenceResultIterator(resultScanner, context.getSequenceManager());
}
return resultScanner;
}
Aggregations