use of org.apache.phoenix.expression.RowValueConstructorExpression in project phoenix by apache.
the class ExpressionCompiler method visitLeave.
@Override
public Expression visitLeave(ComparisonParseNode node, List<Expression> children) throws SQLException {
ParseNode lhsNode = node.getChildren().get(0);
ParseNode rhsNode = node.getChildren().get(1);
Expression lhsExpr = children.get(0);
Expression rhsExpr = children.get(1);
CompareOp op = node.getFilterOp();
if (lhsNode instanceof RowValueConstructorParseNode && rhsNode instanceof RowValueConstructorParseNode) {
int i = 0;
for (; i < Math.min(lhsExpr.getChildren().size(), rhsExpr.getChildren().size()); i++) {
addBindParamMetaData(lhsNode.getChildren().get(i), rhsNode.getChildren().get(i), lhsExpr.getChildren().get(i), rhsExpr.getChildren().get(i));
}
for (; i < lhsExpr.getChildren().size(); i++) {
addBindParamMetaData(lhsNode.getChildren().get(i), null, lhsExpr.getChildren().get(i), null);
}
for (; i < rhsExpr.getChildren().size(); i++) {
addBindParamMetaData(null, rhsNode.getChildren().get(i), null, rhsExpr.getChildren().get(i));
}
} else if (lhsExpr instanceof RowValueConstructorExpression) {
addBindParamMetaData(lhsNode.getChildren().get(0), rhsNode, lhsExpr.getChildren().get(0), rhsExpr);
for (int i = 1; i < lhsExpr.getChildren().size(); i++) {
addBindParamMetaData(lhsNode.getChildren().get(i), null, lhsExpr.getChildren().get(i), null);
}
} else if (rhsExpr instanceof RowValueConstructorExpression) {
addBindParamMetaData(lhsNode, rhsNode.getChildren().get(0), lhsExpr, rhsExpr.getChildren().get(0));
for (int i = 1; i < rhsExpr.getChildren().size(); i++) {
addBindParamMetaData(null, rhsNode.getChildren().get(i), null, rhsExpr.getChildren().get(i));
}
} else {
addBindParamMetaData(lhsNode, rhsNode, lhsExpr, rhsExpr);
}
return wrapGroupByExpression(ComparisonExpression.create(op, children, context.getTempPtr(), context.getCurrentTable().getTable().rowKeyOrderOptimizable()));
}
use of org.apache.phoenix.expression.RowValueConstructorExpression in project phoenix by apache.
the class QueryCompiler method getKeyExpressionCombinations.
private boolean getKeyExpressionCombinations(Pair<Expression, Expression> combination, StatementContext context, SelectStatement select, TableRef table, JoinType type, final List<Expression> joinExpressions, final List<Expression> hashExpressions) throws SQLException {
if ((type != JoinType.Inner && type != JoinType.Semi) || this.noChildParentJoinOptimization)
return false;
Scan scanCopy = ScanUtil.newScan(context.getScan());
StatementContext contextCopy = new StatementContext(statement, context.getResolver(), scanCopy, new SequenceManager(statement));
contextCopy.setCurrentTable(table);
List<Expression> lhsCombination = Lists.<Expression>newArrayList();
boolean complete = WhereOptimizer.getKeyExpressionCombination(lhsCombination, contextCopy, select, joinExpressions);
if (lhsCombination.isEmpty())
return false;
List<Expression> rhsCombination = Lists.newArrayListWithExpectedSize(lhsCombination.size());
for (int i = 0; i < lhsCombination.size(); i++) {
Expression lhs = lhsCombination.get(i);
for (int j = 0; j < joinExpressions.size(); j++) {
if (lhs == joinExpressions.get(j)) {
rhsCombination.add(hashExpressions.get(j));
break;
}
}
}
if (lhsCombination.size() == 1) {
combination.setFirst(lhsCombination.get(0));
combination.setSecond(rhsCombination.get(0));
} else {
combination.setFirst(new RowValueConstructorExpression(lhsCombination, false));
combination.setSecond(new RowValueConstructorExpression(rhsCombination, false));
}
return type == JoinType.Semi && complete;
}
use of org.apache.phoenix.expression.RowValueConstructorExpression in project phoenix by apache.
the class HashCacheClient method evaluateKeyExpression.
/**
* Evaluate the RHS key expression and wrap the result as a new Expression.
* Unlike other types of Expression which will be evaluated and wrapped as a
* single LiteralExpression, RowValueConstructorExpression should be handled
* differently. We should evaluate each child of RVC and wrap them into a new
* RVC Expression, in order to make sure that the later coercion between the
* LHS key expression and this RHS key expression will be successful.
*
* @param keyExpression the RHS key expression
* @param tuple the input tuple
* @param ptr the temporary pointer
* @return the Expression containing the evaluated result
* @throws SQLException
*/
public static Expression evaluateKeyExpression(Expression keyExpression, Tuple tuple, ImmutableBytesWritable ptr) throws SQLException {
if (!(keyExpression instanceof RowValueConstructorExpression)) {
PDataType type = keyExpression.getDataType();
keyExpression.reset();
if (keyExpression.evaluate(tuple, ptr)) {
return LiteralExpression.newConstant(type.toObject(ptr, keyExpression.getSortOrder()), type);
}
return LiteralExpression.newConstant(null, type);
}
List<Expression> children = keyExpression.getChildren();
List<Expression> values = Lists.newArrayListWithExpectedSize(children.size());
for (Expression child : children) {
PDataType type = child.getDataType();
child.reset();
if (child.evaluate(tuple, ptr)) {
values.add(LiteralExpression.newConstant(type.toObject(ptr, child.getSortOrder()), type));
} else {
values.add(LiteralExpression.newConstant(null, type));
}
}
// might be coerced later.
return new RowValueConstructorExpression(values, false);
}
use of org.apache.phoenix.expression.RowValueConstructorExpression in project phoenix by apache.
the class WhereOptimizer method getKeyExpressionCombination.
/**
* Get an optimal combination of key expressions for hash join key range optimization.
* @return returns true if the entire combined expression is covered by key range optimization
* @param result the optimal combination of key expressions
* @param context the temporary context to get scan ranges set by pushKeyExpressionsToScan()
* @param statement the statement being compiled
* @param expressions the join key expressions
* @return the optimal list of key expressions
*/
public static boolean getKeyExpressionCombination(List<Expression> result, StatementContext context, FilterableStatement statement, List<Expression> expressions) throws SQLException {
List<Integer> candidateIndexes = Lists.newArrayList();
final List<Integer> pkPositions = Lists.newArrayList();
PTable table = context.getCurrentTable().getTable();
for (int i = 0; i < expressions.size(); i++) {
Expression expression = expressions.get(i);
// TODO this is a temporary fix for PHOENIX-3029.
if (expression instanceof CoerceExpression && expression.getSortOrder() != expression.getChildren().get(0).getSortOrder()) {
continue;
}
KeyExpressionVisitor visitor = new KeyExpressionVisitor(context, table);
KeyExpressionVisitor.KeySlots keySlots = expression.accept(visitor);
int minPkPos = Integer.MAX_VALUE;
if (keySlots != null) {
Iterator<KeyExpressionVisitor.KeySlot> iterator = keySlots.iterator();
while (iterator.hasNext()) {
KeyExpressionVisitor.KeySlot slot = iterator.next();
if (slot.getPKPosition() < minPkPos) {
minPkPos = slot.getPKPosition();
}
}
if (minPkPos != Integer.MAX_VALUE) {
candidateIndexes.add(i);
pkPositions.add(minPkPos);
}
}
}
if (candidateIndexes.isEmpty())
return false;
Collections.sort(candidateIndexes, new Comparator<Integer>() {
@Override
public int compare(Integer left, Integer right) {
return pkPositions.get(left) - pkPositions.get(right);
}
});
List<Expression> candidates = Lists.newArrayList();
List<List<Expression>> sampleValues = Lists.newArrayList();
for (Integer index : candidateIndexes) {
candidates.add(expressions.get(index));
}
for (int i = 0; i < 2; i++) {
List<Expression> group = Lists.newArrayList();
for (Expression expression : candidates) {
PDataType type = expression.getDataType();
group.add(LiteralExpression.newConstant(type.getSampleValue(), type));
}
sampleValues.add(group);
}
int count = 0;
int offset = table.getBucketNum() == null ? 0 : SaltingUtil.NUM_SALTING_BYTES;
int maxPkSpan = 0;
Expression remaining = null;
while (count < candidates.size()) {
Expression lhs = count == 0 ? candidates.get(0) : new RowValueConstructorExpression(candidates.subList(0, count + 1), false);
Expression firstRhs = count == 0 ? sampleValues.get(0).get(0) : new RowValueConstructorExpression(sampleValues.get(0).subList(0, count + 1), true);
Expression secondRhs = count == 0 ? sampleValues.get(1).get(0) : new RowValueConstructorExpression(sampleValues.get(1).subList(0, count + 1), true);
Expression testExpression = InListExpression.create(Lists.newArrayList(lhs, firstRhs, secondRhs), false, context.getTempPtr(), context.getCurrentTable().getTable().rowKeyOrderOptimizable());
remaining = pushKeyExpressionsToScan(context, statement, testExpression);
if (context.getScanRanges().isPointLookup()) {
count++;
// found the best match
break;
}
int pkSpan = context.getScanRanges().getBoundPkColumnCount() - offset;
if (pkSpan <= maxPkSpan) {
break;
}
maxPkSpan = pkSpan;
count++;
}
result.addAll(candidates.subList(0, count));
return count == candidates.size() && (context.getScanRanges().isPointLookup() || context.getScanRanges().useSkipScanFilter()) && (remaining == null || remaining.equals(LiteralExpression.newConstant(true, Determinism.ALWAYS)));
}
Aggregations