| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF 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. |
| */ |
| package org.apache.vxquery.runtime.functions.arithmetic; |
| |
| import java.io.DataOutput; |
| import java.io.IOException; |
| |
| import org.apache.vxquery.context.DynamicContext; |
| import org.apache.vxquery.datamodel.accessors.atomic.XSDatePointable; |
| import org.apache.vxquery.datamodel.accessors.atomic.XSDateTimePointable; |
| import org.apache.vxquery.datamodel.accessors.atomic.XSDecimalPointable; |
| import org.apache.vxquery.datamodel.accessors.atomic.XSTimePointable; |
| import org.apache.vxquery.datamodel.values.ValueTag; |
| import org.apache.vxquery.exceptions.ErrorCode; |
| import org.apache.vxquery.exceptions.SystemException; |
| import org.apache.vxquery.runtime.functions.cast.CastToDecimalOperation; |
| |
| import org.apache.hyracks.data.std.primitive.DoublePointable; |
| import org.apache.hyracks.data.std.primitive.FloatPointable; |
| import org.apache.hyracks.data.std.primitive.IntegerPointable; |
| import org.apache.hyracks.data.std.primitive.LongPointable; |
| import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; |
| |
| public class DivideOperation extends AbstractArithmeticOperation { |
| protected final ArrayBackedValueStorage abvsInner = new ArrayBackedValueStorage(); |
| private DoublePointable doublep = (DoublePointable) DoublePointable.FACTORY.createPointable(); |
| private XSDecimalPointable decp1 = (XSDecimalPointable) XSDecimalPointable.FACTORY.createPointable(); |
| private XSDecimalPointable decp2 = (XSDecimalPointable) XSDecimalPointable.FACTORY.createPointable(); |
| |
| @Override |
| public void operateDateDate(XSDatePointable datep, XSDatePointable datep2, DynamicContext dCtx, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDateDTDuration(XSDatePointable datep, LongPointable longp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDatetimeDatetime(XSDateTimePointable datetimep, XSDateTimePointable datetimep2, |
| DynamicContext dCtx, DataOutput dOut) throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDatetimeDTDuration(XSDateTimePointable datetimep, LongPointable longp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDatetimeYMDuration(XSDateTimePointable datetimep, IntegerPointable intp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDateYMDuration(XSDatePointable datep, IntegerPointable intp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDecimalDecimal(XSDecimalPointable decp1, XSDecimalPointable decp2, DataOutput dOut) |
| throws SystemException, IOException { |
| // Prepare |
| double value1 = decp1.doubleValue(); |
| double value2 = decp2.doubleValue(); |
| if (value2 == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| // Divide |
| value1 /= value2; |
| // Save |
| abvsInner.reset(); |
| doublep.set(abvsInner.getByteArray(), abvsInner.getStartOffset(), DoublePointable.TYPE_TRAITS.getFixedLength()); |
| doublep.setDouble(value1); |
| CastToDecimalOperation castToDecmial = new CastToDecimalOperation(); |
| castToDecmial.convertDouble(doublep, dOut); |
| } |
| |
| @Override |
| public void operateDecimalDouble(XSDecimalPointable decp1, DoublePointable doublep2, DataOutput dOut) |
| throws SystemException, IOException { |
| double value = decp1.doubleValue(); |
| value /= doublep2.doubleValue(); |
| dOut.write(ValueTag.XS_DOUBLE_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateDecimalDTDuration(XSDecimalPointable decp1, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDecimalFloat(XSDecimalPointable decp1, FloatPointable floatp2, DataOutput dOut) |
| throws SystemException, IOException { |
| float value = decp1.floatValue(); |
| value /= floatp2.floatValue(); |
| dOut.write(ValueTag.XS_FLOAT_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateDecimalInteger(XSDecimalPointable decp1, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| if (longp2.getLong() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| // Convert |
| abvsInner.reset(); |
| decp2.set(abvsInner.getByteArray(), abvsInner.getStartOffset(), XSDecimalPointable.TYPE_TRAITS.getFixedLength()); |
| decp2.setDecimal(longp2.longValue(), (byte) 0); |
| operateDecimalDecimal(decp1, decp2, dOut); |
| } |
| |
| @Override |
| public void operateDecimalYMDuration(XSDecimalPointable decp1, IntegerPointable intp2, DataOutput dOut) |
| throws SystemException, IOException { |
| int value = operateDecimalInt(decp1, intp2.intValue()); |
| dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG); |
| dOut.writeInt(value); |
| } |
| |
| @Override |
| public void operateDoubleDecimal(DoublePointable doublep, XSDecimalPointable decp, DataOutput dOut) |
| throws SystemException, IOException { |
| if (decp.getDecimalValue() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| double value = doublep.doubleValue(); |
| value /= decp.doubleValue(); |
| dOut.write(ValueTag.XS_DOUBLE_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateDoubleDouble(DoublePointable doublep, DoublePointable doublep2, DataOutput dOut) |
| throws SystemException, IOException { |
| double value = doublep.doubleValue(); |
| value /= doublep2.doubleValue(); |
| dOut.write(ValueTag.XS_DOUBLE_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateDoubleDTDuration(DoublePointable doublep, LongPointable longp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDoubleFloat(DoublePointable doublep, FloatPointable floatp, DataOutput dOut) |
| throws SystemException, IOException { |
| double value = doublep.doubleValue(); |
| value /= floatp.doubleValue(); |
| dOut.write(ValueTag.XS_DOUBLE_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateDoubleInteger(DoublePointable doublep, LongPointable longp, DataOutput dOut) |
| throws SystemException, IOException { |
| if (longp.getLong() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| double value = doublep.doubleValue(); |
| value /= longp.doubleValue(); |
| dOut.write(ValueTag.XS_DOUBLE_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateDoubleYMDuration(DoublePointable doublep, IntegerPointable intp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDTDurationDate(LongPointable longp, XSDatePointable datep, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDTDurationDatetime(LongPointable longp, XSDateTimePointable datetimep, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateDTDurationDecimal(LongPointable longp, XSDecimalPointable decp, DataOutput dOut) |
| throws SystemException, IOException { |
| if (decp.getDecimalValue() == 0) { |
| throw new SystemException(ErrorCode.FODT0002); |
| } |
| long value = longp.longValue(); |
| value /= decp.longValue(); |
| dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG); |
| dOut.writeLong(value); |
| } |
| |
| @Override |
| public void operateDTDurationDouble(LongPointable longp, DoublePointable doublep, DataOutput dOut) |
| throws SystemException, IOException { |
| if (Double.isNaN(doublep.doubleValue())) { |
| throw new SystemException(ErrorCode.FOCA0005); |
| } |
| if (doublep.doubleValue() == 0.0) { |
| throw new SystemException(ErrorCode.FODT0002); |
| } |
| double value = longp.doubleValue(); |
| value /= doublep.doubleValue(); |
| dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG); |
| dOut.writeLong((long) value); |
| } |
| |
| @Override |
| public void operateDTDurationDTDuration(LongPointable longp1, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| double value = longp1.longValue(); |
| value /= longp2.longValue(); |
| |
| abvsInner.reset(); |
| doublep.set(abvsInner.getByteArray(), abvsInner.getStartOffset(), DoublePointable.TYPE_TRAITS.getFixedLength()); |
| doublep.setDouble(value); |
| CastToDecimalOperation castToDecmial = new CastToDecimalOperation(); |
| castToDecmial.convertDouble(doublep, dOut); |
| } |
| |
| @Override |
| public void operateDTDurationFloat(LongPointable longp, FloatPointable floatp, DataOutput dOut) |
| throws SystemException, IOException { |
| if (Float.isNaN(floatp.floatValue())) { |
| throw new SystemException(ErrorCode.FOCA0005); |
| } |
| if (floatp.floatValue() == 0.0f) { |
| throw new SystemException(ErrorCode.FODT0002); |
| } |
| float value = longp.floatValue(); |
| value /= floatp.intValue(); |
| dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG); |
| dOut.writeLong((long) value); |
| } |
| |
| @Override |
| public void operateDTDurationInteger(LongPointable longp1, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| if (longp2.getLong() == 0) { |
| throw new SystemException(ErrorCode.FODT0002); |
| } |
| long value = longp1.longValue(); |
| value /= longp2.longValue(); |
| dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG); |
| dOut.writeLong(value); |
| } |
| |
| @Override |
| public void operateDTDurationTime(LongPointable longp, XSTimePointable timep, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateFloatDecimal(FloatPointable floatp1, XSDecimalPointable decp2, DataOutput dOut) |
| throws SystemException, IOException { |
| if (decp2.getDecimalValue() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| float value = floatp1.floatValue(); |
| value /= decp2.floatValue(); |
| dOut.write(ValueTag.XS_FLOAT_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateFloatDouble(FloatPointable floatp1, DoublePointable doublep2, DataOutput dOut) |
| throws SystemException, IOException { |
| double value = floatp1.doubleValue(); |
| value /= doublep2.doubleValue(); |
| dOut.write(ValueTag.XS_DOUBLE_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateFloatDTDuration(FloatPointable floatp1, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateFloatFloat(FloatPointable floatp1, FloatPointable floatp2, DataOutput dOut) |
| throws SystemException, IOException { |
| float value = floatp1.floatValue(); |
| value /= floatp2.floatValue(); |
| dOut.write(ValueTag.XS_FLOAT_TAG); |
| dOut.writeFloat(value); |
| } |
| |
| @Override |
| public void operateFloatInteger(FloatPointable floatp1, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| if (longp2.getLong() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| float value = floatp1.floatValue(); |
| value /= longp2.floatValue(); |
| dOut.write(ValueTag.XS_FLOAT_TAG); |
| dOut.writeFloat(value); |
| } |
| |
| @Override |
| public void operateFloatYMDuration(FloatPointable floatp1, IntegerPointable intp2, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateIntegerDecimal(LongPointable longp1, XSDecimalPointable decp2, DataOutput dOut) |
| throws SystemException, IOException { |
| if (decp2.getDecimalValue() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| abvsInner.reset(); |
| decp1.set(abvsInner.getByteArray(), abvsInner.getStartOffset(), XSDecimalPointable.TYPE_TRAITS.getFixedLength()); |
| decp1.setDecimal(longp1.longValue(), (byte) 0); |
| operateDecimalDecimal(decp1, decp2, dOut); |
| } |
| |
| @Override |
| public void operateIntegerDouble(LongPointable longp, DoublePointable doublep, DataOutput dOut) |
| throws SystemException, IOException { |
| double value = longp.doubleValue(); |
| value /= doublep.doubleValue(); |
| dOut.write(ValueTag.XS_DOUBLE_TAG); |
| dOut.writeDouble(value); |
| } |
| |
| @Override |
| public void operateIntegerDTDuration(LongPointable longp1, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateIntegerFloat(LongPointable longp, FloatPointable floatp, DataOutput dOut) |
| throws SystemException, IOException { |
| float value = longp.floatValue(); |
| value /= floatp.floatValue(); |
| dOut.write(ValueTag.XS_FLOAT_TAG); |
| dOut.writeFloat(value); |
| } |
| |
| @Override |
| public void operateIntegerInteger(LongPointable longp, LongPointable longp2, DataOutput dOut) |
| throws SystemException, IOException { |
| if (longp2.getLong() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| // This is an exception for integer integer operations. The divide operation returns a decimal. |
| double value = longp.doubleValue(); |
| value /= longp2.doubleValue(); |
| |
| abvsInner.reset(); |
| doublep.set(abvsInner.getByteArray(), abvsInner.getStartOffset(), DoublePointable.TYPE_TRAITS.getFixedLength()); |
| doublep.setDouble(value); |
| CastToDecimalOperation castToDecmial = new CastToDecimalOperation(); |
| castToDecmial.convertDouble(doublep, dOut); |
| } |
| |
| @Override |
| public void operateIntegerYMDuration(LongPointable longp, IntegerPointable intp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateTimeDTDuration(XSTimePointable timep, LongPointable longp, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateTimeTime(XSTimePointable timep, XSTimePointable timep2, DynamicContext dCtx, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateYMDurationDate(IntegerPointable intp, XSDatePointable datep, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateYMDurationDatetime(IntegerPointable intp, XSDateTimePointable datetimep, DataOutput dOut) |
| throws SystemException, IOException { |
| throw new SystemException(ErrorCode.XPTY0004); |
| } |
| |
| @Override |
| public void operateYMDurationDecimal(IntegerPointable intp1, XSDecimalPointable decp2, DataOutput dOut) |
| throws SystemException, IOException { |
| int value = operateIntDecimal(intp1.intValue(), decp2); |
| dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG); |
| dOut.writeInt(value); |
| } |
| |
| @Override |
| public void operateYMDurationDouble(IntegerPointable intp, DoublePointable doublep, DataOutput dOut) |
| throws SystemException, IOException { |
| double value = intp.doubleValue(); |
| value /= doublep.doubleValue(); |
| dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG); |
| dOut.writeInt((int) value); |
| } |
| |
| @Override |
| public void operateYMDurationFloat(IntegerPointable intp, FloatPointable floatp, DataOutput dOut) |
| throws SystemException, IOException { |
| float value = intp.floatValue(); |
| value /= floatp.floatValue(); |
| dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG); |
| dOut.writeInt((int) value); |
| } |
| |
| @Override |
| public void operateYMDurationInteger(IntegerPointable intp, LongPointable longp, DataOutput dOut) |
| throws SystemException, IOException { |
| if (longp.getLong() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| int value = intp.intValue(); |
| value /= longp.intValue(); |
| dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG); |
| dOut.writeInt(value); |
| } |
| |
| @Override |
| public void operateYMDurationYMDuration(IntegerPointable intp, IntegerPointable intp2, DataOutput dOut) |
| throws SystemException, IOException { |
| if (intp2.getInteger() == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| double value = intp.intValue(); |
| value /= intp2.intValue(); |
| |
| abvsInner.reset(); |
| doublep.set(abvsInner.getByteArray(), abvsInner.getStartOffset(), DoublePointable.TYPE_TRAITS.getFixedLength()); |
| doublep.setDouble(value); |
| CastToDecimalOperation castToDecmial = new CastToDecimalOperation(); |
| castToDecmial.convertDouble(doublep, dOut); |
| } |
| |
| public int operateIntDecimal(int intValue, XSDecimalPointable decp2) throws SystemException, IOException { |
| abvsInner.reset(); |
| // Prepare |
| double value1 = intValue; |
| double value2 = decp2.doubleValue(); |
| if (value2 == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| // Divide |
| value1 /= value2; |
| // Save |
| return (int) value1; |
| } |
| |
| public int operateDecimalInt(XSDecimalPointable decp1, int intValue) throws SystemException, IOException { |
| abvsInner.reset(); |
| // Prepare |
| double value1 = decp1.doubleValue(); |
| double value2 = intValue; |
| if (value2 == 0) { |
| throw new SystemException(ErrorCode.FOAR0001); |
| } |
| // Divide |
| value1 /= value2; |
| // Save |
| return (int) value1; |
| } |
| |
| } |