Class SQLDecimal

  • All Implemented Interfaces:
    java.io.Externalizable, java.io.Serializable, java.lang.Comparable, Formatable, Storable, TypedFormat, DataValueDescriptor, NumberDataValue, Orderable, VariableSizeDataValue

    public final class SQLDecimal
    extends NumberDataType
    implements VariableSizeDataValue
    SQLDecimal satisfies the DataValueDescriptor interfaces (i.e., OrderableDataType). It implements a numeric/decimal column, e.g. for * storing a column value; it can be specified when constructed to not allow nulls. Nullability cannot be changed after construction, as it affects the storage size and mechanism.

    Because OrderableDataType is a subtype of DataType, SQLDecimal can play a role in either a DataType/Row or a OrderableDataType/Row, interchangeably.

    We assume the store has a flag for nullness of the value, and simply return a 0-length array for the stored form when the value is null.

    See Also:
    Serialized Form
    • Field Detail

      • value

        private java.math.BigDecimal value
        object state. Note that scale and precision are always determined dynamically from value when it is not null. The field value can be null without the data value being null. In this case the value is stored in rawData and rawScale. This is to allow the minimal amount of work to read a SQLDecimal from disk. Creating the BigDecimal is expensive as it requires allocating three objects, the last two are a waste in the case the row does not qualify or the row will be written out by the sorter before being returned to the application.

        This means that this field must be accessed for read indirectly through the getBigDecimal() method, and when setting it the rawData field must be set to null.

      • rawData

        private byte[] rawData
        See comments for value
      • rawScale

        private int rawScale
        See comments for value
      • BASE_MEMORY_USAGE

        private static final int BASE_MEMORY_USAGE
      • BIG_DECIMAL_MEMORY_USAGE

        private static final int BIG_DECIMAL_MEMORY_USAGE
    • Constructor Detail

      • SQLDecimal

        public SQLDecimal()
        no-arg constructor, required by Formattable
      • SQLDecimal

        public SQLDecimal​(java.math.BigDecimal val)
      • SQLDecimal

        public SQLDecimal​(java.lang.String val)
    • Method Detail

      • estimateMemoryUsage

        public int estimateMemoryUsage()
        Description copied from interface: DataValueDescriptor
        Estimate the memory usage in bytes of the data value and the overhead of the class.
        Specified by:
        estimateMemoryUsage in interface DataValueDescriptor
        Returns:
        the estimated memory usage
      • getDouble

        public double getDouble()
                         throws StandardException
        If we have a value that is greater than the maximum double, exception is thrown. Otherwise, ok. If the value is less than can be represented by a double, ti will get set to the smallest double value.
        Specified by:
        getDouble in interface DataValueDescriptor
        Overrides:
        getDouble in class DataType
        Returns:
        The data value as a double.
        Throws:
        StandardException - thrown on failure to convert
      • getBigDecimal

        private java.math.BigDecimal getBigDecimal()
      • typeToBigDecimal

        public int typeToBigDecimal()
        DECIMAL implementation. Convert to a BigDecimal using getObject which will return a BigDecimal
        Specified by:
        typeToBigDecimal in interface DataValueDescriptor
        Overrides:
        typeToBigDecimal in class NumberDataType
        Returns:
        Types.CHAR for String conversion through getString Types.DECIMAL for BigDecimal through getObject or Types.BIGINT for long conversion through getLong
      • getBoolean

        public boolean getBoolean()
        Description copied from class: DataType
        Gets the value in the data value descriptor as a boolean. Throws an exception if the data value is not receivable as a boolean.
        Specified by:
        getBoolean in interface DataValueDescriptor
        Overrides:
        getBoolean in class DataType
        Returns:
        The data value as a boolean.
      • getString

        public java.lang.String getString()
        Description copied from interface: DataValueDescriptor
        Gets the value in the data value descriptor as a String. Throws an exception if the data value is not a string.
        Specified by:
        getString in interface DataValueDescriptor
        Returns:
        The data value as a String.
      • getObject

        public java.lang.Object getObject()
        Description copied from class: DataType
        Gets the value in the data value descriptor as a int. Throws an exception if the data value is not receivable as a int.
        Specified by:
        getObject in interface DataValueDescriptor
        Overrides:
        getObject in class DataType
        Returns:
        The data value as a int.
      • setFrom

        protected void setFrom​(DataValueDescriptor theValue)
                        throws StandardException
        Description copied from class: DataType
        Set the value of this DataValueDescriptor based on the value of the specified DataValueDescriptor.
        Overrides:
        setFrom in class DataType
        Parameters:
        theValue - The DataValueDescriptor that holds the value to which we want to set this DataValueDescriptor's value.
        Throws:
        StandardException
      • getLength

        public int getLength()
        Description copied from interface: DataValueDescriptor
        Gets the length of the data value. The meaning of this is implementation-dependent. For string types, it is the number of characters in the string. For numeric types, it is the number of bytes used to store the number. This is the actual length of this value, not the length of the type it was defined as. For example, a VARCHAR value may be shorter than the declared VARCHAR (maximum) length.
        Specified by:
        getLength in interface DataValueDescriptor
        Returns:
        The length of the data value
      • isNull

        public boolean isNull()
        Description copied from interface: Storable
        Return whether the value is null or not.
        Specified by:
        isNull in interface Storable
        Returns:
        true if the value is null and false otherwise.
        See Also:
        Storable.isNull()
      • writeExternal

        public void writeExternal​(java.io.ObjectOutput out)
                           throws java.io.IOException
        Distill the BigDecimal to a byte array and write out:
        • scale (zero or positive) as a byte
        • length of byte array as a byte
        • the byte array
        Specified by:
        writeExternal in interface java.io.Externalizable
        Throws:
        java.io.IOException
      • readExternal

        public void readExternal​(java.io.ObjectInput in)
                          throws java.io.IOException
        Note the use of rawData: we reuse the array if the incoming array is the same length or smaller than the array length.
        Specified by:
        readExternal in interface java.io.Externalizable
        Throws:
        java.io.IOException
        See Also:
        Externalizable.readExternal(java.io.ObjectInput)
      • cloneValue

        public DataValueDescriptor cloneValue​(boolean forceMaterialization)
        Description copied from interface: DataValueDescriptor
        Clone this DataValueDescriptor. Results in a new object that has the same value as this but can be modified independently.

        Even though the objects can be modified independently regardless of the value of forceMaterialization, both the clone and the original may be dependent on the store state if forceMaterialization is set to false. An example is if you need to access the value you just read using cloneValue after the current transaction has ended, or after the source result set has been closed.

        Specified by:
        cloneValue in interface DataValueDescriptor
        Parameters:
        forceMaterialization - any streams representing the data value will be materialized if true, the data value will be kept as a stream if possible if false
        Returns:
        A clone of the DataValueDescriptor with the same initial value as this.
        See Also:
        DataValueDescriptor.cloneValue(boolean)
      • setValueFromResultSet

        public void setValueFromResultSet​(java.sql.ResultSet resultSet,
                                          int colNumber,
                                          boolean isNullable)
                                   throws java.sql.SQLException
        Description copied from interface: DataValueDescriptor
        Set the value based on the value for the specified DataValueDescriptor from the specified ResultSet.
        Specified by:
        setValueFromResultSet in interface DataValueDescriptor
        Parameters:
        resultSet - The specified ResultSet.
        colNumber - The 1-based column # into the resultSet.
        isNullable - Whether or not the column is nullable (No need to call wasNull() if not)
        Throws:
        java.sql.SQLException - Thrown on error
        See Also:
        DataValueDescriptor.setValueFromResultSet(java.sql.ResultSet, int, boolean)
      • setInto

        public final void setInto​(java.sql.PreparedStatement ps,
                                  int position)
                           throws java.sql.SQLException
        Set the value into a PreparedStatement.
        Specified by:
        setInto in interface DataValueDescriptor
        Overrides:
        setInto in class DataType
        Throws:
        java.sql.SQLException - Error setting value in PreparedStatement
      • setValue

        public void setValue​(java.lang.String theValue)
                      throws StandardException
        WARNING there is no checking to make sure that theValue doesn't exceed the precision/scale of the current SQLDecimal. It is just assumed that the SQLDecimal is supposed to take the precision/scale of the BigDecimalized String.
        Specified by:
        setValue in interface DataValueDescriptor
        Overrides:
        setValue in class DataType
        Parameters:
        theValue - The BigDecimal value to set this DataValueDescriptor to
        Throws:
        StandardException - throws NumberFormatException when the String format is not recognized.
      • setValue

        public void setValue​(java.lang.Number theValue)
                      throws StandardException
        Called when setting a DECIMAL value internally or from through a procedure or function. Handles long in addition to BigDecimal to handle identity being stored as a long but returned as a DECIMAL.
        Specified by:
        setValue in interface NumberDataValue
        Overrides:
        setValue in class NumberDataType
        Parameters:
        theValue - An Number containing the value to set this NumberDataValue to. Null means set the value to SQL null.
        Throws:
        StandardException - Thrown on error
        See Also:
        NumberDataValue.setValue(java.lang.Number)
      • typePrecedence

        public int typePrecedence()
        Description copied from class: DataType
        Each built-in type in JSQL has a precedence. This precedence determines how to do type promotion when using binary operators. For example, float has a higher precedence than int, so when adding an int to a float, the result type is float. The precedence for some types is arbitrary. For example, it doesn't matter what the precedence of the boolean type is, since it can't be mixed with other types. But the precedence for the number types is critical. The SQL standard requires that exact numeric types be promoted to approximate numeric when one operator uses both. Also, the precedence is arranged so that one will not lose precision when promoting a type.
        Specified by:
        typePrecedence in interface DataValueDescriptor
        Overrides:
        typePrecedence in class DataType
        Returns:
        The precedence of this type.
        See Also:
        DataValueDescriptor.typePrecedence()
      • setCoreValue

        private void setCoreValue​(java.math.BigDecimal theValue)
      • setCoreValue

        private void setCoreValue​(double theValue)
      • normalize

        public void normalize​(DataTypeDescriptor desiredType,
                              DataValueDescriptor source)
                       throws StandardException
        Normalization method - this method may be called when putting a value into a SQLDecimal, for example, when inserting into a SQLDecimal column. See NormalizeResultSet in execution.

        Note that truncation is allowed on the decimal portion of a numeric only.

        Specified by:
        normalize in interface DataValueDescriptor
        Overrides:
        normalize in class DataType
        Parameters:
        desiredType - The type to normalize the source column to
        source - The value to normalize
        Throws:
        StandardException - Thrown for null into non-nullable column, and for truncation error
      • isNegative

        protected boolean isNegative()
        This method implements the isNegative method.
        Specified by:
        isNegative in class NumberDataType
        Returns:
        A boolean. If this.value is negative, return true. For positive values or null, return false.
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object
      • setWidth

        public void setWidth​(int desiredPrecision,
                             int desiredScale,
                             boolean errorOnTrunc)
                      throws StandardException
        Set the precision/scale of the to the desired values. Used when CASTing. Ideally we'd recycle normalize(), but the use is different.
        Specified by:
        setWidth in interface VariableSizeDataValue
        Parameters:
        desiredPrecision - the desired precision -- IGNORE_PREICISION if it is to be ignored.
        desiredScale - the desired scale
        errorOnTrunc - throw error on truncation (ignored -- always thrown if we truncate the non-decimal part of the value)
        Throws:
        StandardException - Thrown on non-zero truncation if errorOnTrunc is true
      • getDecimalValuePrecision

        public int getDecimalValuePrecision()
        Return the SQL scale of this value, number of digits after the decimal point, or zero for a whole number. This does not match the return from BigDecimal.scale() since in J2SE 5.0 onwards that can return negative scales.
      • getDecimalValueScale

        public int getDecimalValueScale()
        Return the SQL scale of this value, number of digits after the decimal point, or zero for a whole number. This does not match the return from BigDecimal.scale() since in J2SE 5.0 onwards that can return negative scales.
      • getBigDecimal

        public static java.math.BigDecimal getBigDecimal​(DataValueDescriptor value)
                                                  throws StandardException
        Get a BigDecimal representing the value of a DataValueDescriptor
        Parameters:
        value - Non-null value to be converted
        Returns:
        BigDecimal value
        Throws:
        StandardException - Invalid conversion or out of range.
      • getWholeDigits

        private static int getWholeDigits​(java.math.BigDecimal decimalValue)
        Calculate the number of digits to the left of the decimal point of the passed in value.
        Parameters:
        decimalValue - Value to get whole digits from, never null.
        Returns:
        number of whole digits.