Search in sources :

Example 1 with LongSubtractExpression

use of org.apache.phoenix.expression.LongSubtractExpression in project phoenix by apache.

the class ExpressionCompiler method visitLeave.

@Override
public Expression visitLeave(SubtractParseNode node, List<Expression> children) throws SQLException {
    return visitLeave(node, children, new ArithmeticExpressionBinder() {

        @Override
        public PDatum getBindMetaData(int i, List<Expression> children, final Expression expression) {
            final PDataType type;
            // we know that the first parameter must be a date type too.
            if (i == 0 && (type = children.get(1).getDataType()) != null && type.isCoercibleTo(PDate.INSTANCE)) {
                return new PDatum() {

                    @Override
                    public boolean isNullable() {
                        return expression.isNullable();
                    }

                    @Override
                    public PDataType getDataType() {
                        return type;
                    }

                    @Override
                    public Integer getMaxLength() {
                        return expression.getMaxLength();
                    }

                    @Override
                    public Integer getScale() {
                        return expression.getScale();
                    }

                    @Override
                    public SortOrder getSortOrder() {
                        return expression.getSortOrder();
                    }
                };
            } else if (expression.getDataType() != null && expression.getDataType().isCoercibleTo(PDate.INSTANCE)) {
                return new // Same as with addition
                PDatum() {

                    @Override
                    public boolean isNullable() {
                        return expression.isNullable();
                    }

                    @Override
                    public PDataType getDataType() {
                        return PDecimal.INSTANCE;
                    }

                    @Override
                    public Integer getMaxLength() {
                        return expression.getMaxLength();
                    }

                    @Override
                    public Integer getScale() {
                        return expression.getScale();
                    }

                    @Override
                    public SortOrder getSortOrder() {
                        return expression.getSortOrder();
                    }
                };
            }
            // Otherwise just go with what was calculated for the expression
            return expression;
        }
    }, new ArithmeticExpressionFactory() {

        @Override
        public Expression create(ArithmeticParseNode node, List<Expression> children) throws SQLException {
            int i = 0;
            PDataType theType = null;
            Expression e1 = children.get(0);
            Expression e2 = children.get(1);
            Determinism determinism = e1.getDeterminism().combine(e2.getDeterminism());
            PDataType type1 = e1.getDataType();
            PDataType type2 = e2.getDataType();
            // TODO: simplify this special case for DATE conversion
            /**
                 * For date1-date2, we want to coerce to a LONG because this
                 * cannot be compared against another date. It has essentially
                 * become a number. For date1-5, we want to preserve the DATE
                 * type because this can still be compared against another date
                 * and cannot be multiplied or divided. Any other time occurs is
                 * an error. For example, 5-date1 is an error. The nulls occur if
                 * we have bind variables.
                 */
            boolean isType1Date = type1 != null && type1 != PTimestamp.INSTANCE && type1 != PUnsignedTimestamp.INSTANCE && type1.isCoercibleTo(PDate.INSTANCE);
            boolean isType2Date = type2 != null && type2 != PTimestamp.INSTANCE && type2 != PUnsignedTimestamp.INSTANCE && type2.isCoercibleTo(PDate.INSTANCE);
            if (isType1Date || isType2Date) {
                if (isType1Date && isType2Date) {
                    i = 2;
                    theType = PDecimal.INSTANCE;
                } else if (isType1Date && type2 != null && type2.isCoercibleTo(PDecimal.INSTANCE)) {
                    i = 2;
                    theType = PDate.INSTANCE;
                } else if (type1 == null || type2 == null) {
                    /*
                         * FIXME: Could be either a Date or BigDecimal, but we
                         * don't know if we're comparing to a date or a number
                         * which would be disambiguate it.
                         */
                    i = 2;
                    theType = null;
                }
            } else if (type1 == PTimestamp.INSTANCE || type2 == PTimestamp.INSTANCE) {
                i = 2;
                theType = PTimestamp.INSTANCE;
            } else if (type1 == PUnsignedTimestamp.INSTANCE || type2 == PUnsignedTimestamp.INSTANCE) {
                i = 2;
                theType = PUnsignedTimestamp.INSTANCE;
            }
            for (; i < children.size(); i++) {
                // This logic finds the common type to which all child types are coercible
                // without losing precision.
                Expression e = children.get(i);
                determinism = determinism.combine(e.getDeterminism());
                PDataType type = e.getDataType();
                if (type == null) {
                    continue;
                } else if (type.isCoercibleTo(PLong.INSTANCE)) {
                    if (theType == null) {
                        theType = PLong.INSTANCE;
                    }
                } else if (type == PDecimal.INSTANCE) {
                    // unless we're doing date arithmetic.
                    if (theType == null || !theType.isCoercibleTo(PDate.INSTANCE)) {
                        theType = PDecimal.INSTANCE;
                    }
                } else if (type.isCoercibleTo(PDouble.INSTANCE)) {
                    // unless we're doing date arithmetic or we've found another child of type DECIMAL
                    if (theType == null || (theType != PDecimal.INSTANCE && !theType.isCoercibleTo(PDate.INSTANCE))) {
                        theType = PDouble.INSTANCE;
                    }
                } else {
                    throw TypeMismatchException.newException(type, node.toString());
                }
            }
            if (theType == PDecimal.INSTANCE) {
                return new DecimalSubtractExpression(children);
            } else if (theType == PLong.INSTANCE) {
                return new LongSubtractExpression(children);
            } else if (theType == PDouble.INSTANCE) {
                return new DoubleSubtractExpression(children);
            } else if (theType == null) {
                return LiteralExpression.newConstant(null, theType, determinism);
            } else if (theType == PTimestamp.INSTANCE || theType == PUnsignedTimestamp.INSTANCE) {
                return new TimestampSubtractExpression(children);
            } else if (theType.isCoercibleTo(PDate.INSTANCE)) {
                return new DateSubtractExpression(children);
            } else {
                throw TypeMismatchException.newException(theType, node.toString());
            }
        }
    });
}
Also used : Determinism(org.apache.phoenix.expression.Determinism) SQLException(java.sql.SQLException) SortOrder(org.apache.phoenix.schema.SortOrder) ArithmeticParseNode(org.apache.phoenix.parse.ArithmeticParseNode) TimestampSubtractExpression(org.apache.phoenix.expression.TimestampSubtractExpression) DoubleSubtractExpression(org.apache.phoenix.expression.DoubleSubtractExpression) PDatum(org.apache.phoenix.schema.PDatum) LongSubtractExpression(org.apache.phoenix.expression.LongSubtractExpression) PDataType(org.apache.phoenix.schema.types.PDataType) DecimalAddExpression(org.apache.phoenix.expression.DecimalAddExpression) TimestampSubtractExpression(org.apache.phoenix.expression.TimestampSubtractExpression) ArrayConstructorExpression(org.apache.phoenix.expression.ArrayConstructorExpression) Expression(org.apache.phoenix.expression.Expression) LikeExpression(org.apache.phoenix.expression.LikeExpression) ByteBasedLikeExpression(org.apache.phoenix.expression.ByteBasedLikeExpression) DoubleSubtractExpression(org.apache.phoenix.expression.DoubleSubtractExpression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) InListExpression(org.apache.phoenix.expression.InListExpression) DateSubtractExpression(org.apache.phoenix.expression.DateSubtractExpression) ArrayElemRefExpression(org.apache.phoenix.expression.function.ArrayElemRefExpression) CaseExpression(org.apache.phoenix.expression.CaseExpression) DoubleDivideExpression(org.apache.phoenix.expression.DoubleDivideExpression) NotExpression(org.apache.phoenix.expression.NotExpression) DoubleAddExpression(org.apache.phoenix.expression.DoubleAddExpression) DecimalDivideExpression(org.apache.phoenix.expression.DecimalDivideExpression) RowKeyColumnExpression(org.apache.phoenix.expression.RowKeyColumnExpression) RowValueConstructorExpression(org.apache.phoenix.expression.RowValueConstructorExpression) RoundTimestampExpression(org.apache.phoenix.expression.function.RoundTimestampExpression) StringConcatExpression(org.apache.phoenix.expression.StringConcatExpression) ComparisonExpression(org.apache.phoenix.expression.ComparisonExpression) TimestampAddExpression(org.apache.phoenix.expression.TimestampAddExpression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) StringBasedLikeExpression(org.apache.phoenix.expression.StringBasedLikeExpression) ArrayAnyComparisonExpression(org.apache.phoenix.expression.function.ArrayAnyComparisonExpression) DecimalSubtractExpression(org.apache.phoenix.expression.DecimalSubtractExpression) ModulusExpression(org.apache.phoenix.expression.ModulusExpression) DoubleMultiplyExpression(org.apache.phoenix.expression.DoubleMultiplyExpression) DecimalMultiplyExpression(org.apache.phoenix.expression.DecimalMultiplyExpression) DateAddExpression(org.apache.phoenix.expression.DateAddExpression) RoundDecimalExpression(org.apache.phoenix.expression.function.RoundDecimalExpression) LongAddExpression(org.apache.phoenix.expression.LongAddExpression) LongSubtractExpression(org.apache.phoenix.expression.LongSubtractExpression) IsNullExpression(org.apache.phoenix.expression.IsNullExpression) AndExpression(org.apache.phoenix.expression.AndExpression) LongMultiplyExpression(org.apache.phoenix.expression.LongMultiplyExpression) ArrayAllComparisonExpression(org.apache.phoenix.expression.function.ArrayAllComparisonExpression) OrExpression(org.apache.phoenix.expression.OrExpression) LongDivideExpression(org.apache.phoenix.expression.LongDivideExpression) DecimalSubtractExpression(org.apache.phoenix.expression.DecimalSubtractExpression) DateSubtractExpression(org.apache.phoenix.expression.DateSubtractExpression)

Aggregations

SQLException (java.sql.SQLException)1 AndExpression (org.apache.phoenix.expression.AndExpression)1 ArrayConstructorExpression (org.apache.phoenix.expression.ArrayConstructorExpression)1 ByteBasedLikeExpression (org.apache.phoenix.expression.ByteBasedLikeExpression)1 CaseExpression (org.apache.phoenix.expression.CaseExpression)1 CoerceExpression (org.apache.phoenix.expression.CoerceExpression)1 ComparisonExpression (org.apache.phoenix.expression.ComparisonExpression)1 DateAddExpression (org.apache.phoenix.expression.DateAddExpression)1 DateSubtractExpression (org.apache.phoenix.expression.DateSubtractExpression)1 DecimalAddExpression (org.apache.phoenix.expression.DecimalAddExpression)1 DecimalDivideExpression (org.apache.phoenix.expression.DecimalDivideExpression)1 DecimalMultiplyExpression (org.apache.phoenix.expression.DecimalMultiplyExpression)1 DecimalSubtractExpression (org.apache.phoenix.expression.DecimalSubtractExpression)1 Determinism (org.apache.phoenix.expression.Determinism)1 DoubleAddExpression (org.apache.phoenix.expression.DoubleAddExpression)1 DoubleDivideExpression (org.apache.phoenix.expression.DoubleDivideExpression)1 DoubleMultiplyExpression (org.apache.phoenix.expression.DoubleMultiplyExpression)1 DoubleSubtractExpression (org.apache.phoenix.expression.DoubleSubtractExpression)1 Expression (org.apache.phoenix.expression.Expression)1 InListExpression (org.apache.phoenix.expression.InListExpression)1