Search in sources :

Example 1 with CoerceExpression

use of org.apache.phoenix.expression.CoerceExpression 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)));
}
Also used : PTable(org.apache.phoenix.schema.PTable) Hint(org.apache.phoenix.parse.HintNode.Hint) PDataType(org.apache.phoenix.schema.types.PDataType) BaseExpression(org.apache.phoenix.expression.BaseExpression) BaseTerminalExpression(org.apache.phoenix.expression.BaseTerminalExpression) Expression(org.apache.phoenix.expression.Expression) LikeExpression(org.apache.phoenix.expression.LikeExpression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) InListExpression(org.apache.phoenix.expression.InListExpression) RowKeyColumnExpression(org.apache.phoenix.expression.RowKeyColumnExpression) RowValueConstructorExpression(org.apache.phoenix.expression.RowValueConstructorExpression) IsNullExpression(org.apache.phoenix.expression.IsNullExpression) AndExpression(org.apache.phoenix.expression.AndExpression) ComparisonExpression(org.apache.phoenix.expression.ComparisonExpression) OrExpression(org.apache.phoenix.expression.OrExpression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) ArrayList(java.util.ArrayList) RowValueConstructorExpression(org.apache.phoenix.expression.RowValueConstructorExpression)

Aggregations

ArrayList (java.util.ArrayList)1 Collections.singletonList (java.util.Collections.singletonList)1 List (java.util.List)1 AndExpression (org.apache.phoenix.expression.AndExpression)1 BaseExpression (org.apache.phoenix.expression.BaseExpression)1 BaseTerminalExpression (org.apache.phoenix.expression.BaseTerminalExpression)1 CoerceExpression (org.apache.phoenix.expression.CoerceExpression)1 ComparisonExpression (org.apache.phoenix.expression.ComparisonExpression)1 Expression (org.apache.phoenix.expression.Expression)1 InListExpression (org.apache.phoenix.expression.InListExpression)1 IsNullExpression (org.apache.phoenix.expression.IsNullExpression)1 LikeExpression (org.apache.phoenix.expression.LikeExpression)1 LiteralExpression (org.apache.phoenix.expression.LiteralExpression)1 OrExpression (org.apache.phoenix.expression.OrExpression)1 RowKeyColumnExpression (org.apache.phoenix.expression.RowKeyColumnExpression)1 RowValueConstructorExpression (org.apache.phoenix.expression.RowValueConstructorExpression)1 Hint (org.apache.phoenix.parse.HintNode.Hint)1 PTable (org.apache.phoenix.schema.PTable)1 PDataType (org.apache.phoenix.schema.types.PDataType)1