Casting

Casting changes a value from one data type to another. This guide shows how to use type casts in query strings to control column types. It covers common numeric and string conversions, then casts on values from Groovy variables, closures, and classes.

In tables, casting gives a column the data type that later operations need. Casting to a Java primitive type also stores the values in compact primitive columns instead of Object or BigDecimal columns.

Type casts

A type cast is an expression that converts a value from one data type to another:

In Deephaven, type casts in query strings convert a value or column to another data type. They use Java syntax and follow these rules:

  • Between primitives: a cast between two numeric primitive types widens or narrows the value:
    • Widening, such as (long) on an int, keeps the value.
    • Narrowing, such as (int) on a double, can lose information. (int) drops a double's fractional part.
    • A value outside the target type's range wraps or clamps. A double outside the float range becomes infinity.
    • A result that equals the target type's null constant reads as null. For byte, that constant is -128.
  • Boxed to primitive: a boxed type is a Java object that wraps a primitive value, such as java.lang.Double. A cast from a boxed type to a primitive type works only for the matching primitive type or a wider one.
  • Other objects to primitive: a cast from any other object type, such as java.lang.Object or java.math.BigDecimal, to a numeric primitive type other than char converts the value with the matching java.lang.Number method, such as doubleValue. It works whenever the value is a number, even where a plain Java cast would fail or not compile.
  • To an object type: a cast to an object type, such as (String), is a plain Java cast. It sets the column type. It works only when the value is already an instance of that type, or when it boxes a primitive into its own boxed type or a supertype, such as (Integer) or (Object) on an int. (String) is short for (java.lang.String).
  • Null safety: casts to primitive types other than boolean are null-safe. A null value becomes the null constant of the target type.

For more casting examples, see the casting reference.

Common casting scenarios

Numeric conversions

The following query applies a numeric cast to each column:

  • ByteVal: (byte)128 overflows to -128. That value is the byte null constant, so ByteVal reads as null.
  • ShortVal: (short)32767 is the largest short value, so it fits and is unchanged.
  • IntVal: (int)3.99 truncates to 3.
  • LongVal and DoubleVal: (long) and (double) widen the int column IntVal.
  • FloatVal: (float) rounds a double literal to float precision.

The sourceMeta table, from meta, lists each column's resulting type:

String conversions

A Java cast can't convert between strings and numbers, so call a conversion function instead. parseInt parses a string as an int, and Integer.toString formats an int as a string:

Casts with Groovy objects

How you cast a value from Groovy depends on where it comes from: a Groovy variable, a Groovy closure, or a method of a Groovy class. The following sections cover each.

Groovy variables

Groovy decimal literals such as 3.14159 are java.math.BigDecimal objects, so a Groovy variable holding one produces a BigDecimal column. A type cast converts it to a Java primitive, following the Other objects to primitive rule under Type casts.

BigDecimal has arbitrary precision and primitives do not, so the cast can round the value. In the following query, (float) rounds a to float precision:

Groovy closures

Groovy closures called in query strings return java.lang.Object, because the query engine calls the closure's generic call method and does not see the types the closure declares. Use a type cast when you need a specific column type for the result.

The following example uses a type cast to convert the return value of a Groovy closure to a java.lang.String:

Groovy classes

Methods of Groovy classes called in query strings produce columns of their declared return type. A method declared with def returns java.lang.Object, so use a type cast when you need a specific column type for its result. The Other objects to primitive rule under Type casts makes a numeric cast such as (int) work on that Object.

The following example casts the results of the static method multiplyModulo and the instance method plusModulo. It first imports MyClass into the query library so the query strings can call its static methods by class name. Groovy classes explains this import in more detail.

Column X needs no cast, because changeValue declares an int return type. Column Q has no cast, so sourceMeta shows its type as java.lang.Object. The casts give Y the double type and Z the int type.