c

com.snowflake.snowpark

UDAFRegistration

class UDAFRegistration extends Logging

Provides methods to register a UDAF (user-defined aggregate function) in the Snowflake database.

Session.udaf returns an object of this class.

To register a UDAF, you must:

  1. Define a UDAF class.
  2. Create an instance of that class, and register that instance as a UDAF.

The next sections describe these steps in more detail.

Defining the UDAF Class

Define a class that inherits from one of the UDAF[N] classes (e.g. UDAF1, UDAF2, etc.), where n specifies the number of input arguments for your UDAF. For example, if your UDAF passes in 2 input arguments, extend the UDAF2 class.

In your class, override the following methods:

  • initialize(), which returns the initial state of the aggregation.
  • accumulate(), which updates the aggregation state with a new input row.
  • merge(), which merges two aggregation states into one.
  • terminate(), which produces the final output value from the aggregation state.
  • outputType(), which returns a types.DataType object that describes the type of the returned value.

Supported Data Types

Snowflake supports the following data types for the input arguments and return value of a UDAF:

SQL Type

Scala Type

Java Type

Notes

NUMBER

Short or Option[Short]

Short or java.lang.Short

Supported

NUMBER

Int or Option[Int]

Integer

Supported

NUMBER

Long or Option[Long]

Long or java.lang.Long

Supported

FLOAT

Float or Option[Float]

Float or java.lang.Float

Supported

DOUBLE

Double or Option[Double]

Double

Supported

NUMBER

java.math.BigDecimal

java.math.BigDecimal

Supported

VARCHAR

String or java.lang.String

java.lang.String

Supported

BOOL

Boolean or Option[Boolean]

Boolean

Supported

DATE

java.sql.Date

java.sql.Date

Supported

TIME

java.sql.Time

java.sql.Time

Supported

TIMESTAMP

java.sql.Timestamp

java.sql.Timestamp

Supported

BINARY

Array[Byte]

byte[]

Supported

ARRAY

Array[String] or Array[Variant]

String[] or Variant[]

Supported array of type Array[String] or Array[Variant]

OBJECT

Map[String, String] or Map[String, Variant]

Map

For Scala, supported mutable map of type scala.collection.mutable.Map[String, String] or scala.collection.mutable.Map[String, Variant]. For Java, use inputSchema() to specify types.

VARIANT

com.snowflake.snowpark.types.Variant

Variant

Supported

Note: GEOGRAPHY and GEOMETRY types are not supported for UDAF input arguments or return values.

Note: Structured types (ARRAY, OBJECT, MAP with nested types) have limited support. For complex nested structures, consider using VARIANT type and performing conversion in your UDAF code.

Aggregation State Requirements

The aggregation state class must be serializable. To ensure compatibility with Kryo serialization:

  • For best compatibility: The state class should implement java.io.Serializable and have a public no-arg constructor.
  • For Scala case classes or classes without no-arg constructors: Kryo uses Objenesis to instantiate objects without calling constructors. This works when the server has Objenesis support enabled.
  • For custom serialization: Implement java.io.Externalizable for fine-grained control over serialization.

Example of a UDAF Class

The following is an example of a UDAF class that computes the average of integers. The state is a custom class that holds the sum and count.

The UDAF passes in 1 argument, so the class extends UDAF1.

// State class must be Serializable with a no-arg constructor for Kryo deserialization
class AvgState extends Serializable {
    var sum: Long = 0L
    var count: Long = 0L
}

class MyAvgUDAF extends UDAF1[AvgState, Double, Int] {
    override def initialize(): AvgState = new AvgState()
    override def accumulate(state: AvgState, input: Int): AvgState = {
        state.sum += input
        state.count += 1
        state
    }
    override def merge(state1: AvgState, state2: AvgState): AvgState = {
        state1.sum += state2.sum
        state1.count += state2.count
        state1
    }
    override def terminate(state: AvgState): Double = {
        if (state.count == 0) 0.0 else state.sum.toDouble / state.count
    }
    override def outputType(): DataType = DoubleType
}

Registering the UDAF

Next, create an instance of the new class, and register the class by calling one of the UDAFRegistration methods. You can register a temporary or permanent UDAF by name.

Registering a Temporary UDAF By Name

To register a temporary UDAF by name, call registerTemporary, passing in a name for the UDAF and an instance of the UDAF class. For example:

// Use the MyAvgUDAF defined in previous example.
val myAvg = session.udaf.registerTemporary("my_avg", new MyAvgUDAF())
df.select(myAvg(col("a"))).show()

Registering a Permanent UDAF By Name

If you need to use the UDAF in subsequent sessions, register a permanent UDAF.

When registering a permanent UDAF, you must specify a stage where the registration method will upload the JAR files for the UDAF and its dependencies. For example:

val myAvg = session.udaf.registerPermanent("my_avg", new MyAvgUDAF(), "@myStage")
df.select(myAvg(col("a"))).show()
Since

1.19.0

Linear Supertypes
Logging, AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. UDAFRegistration
  2. Logging
  3. AnyRef
  4. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Instance Constructors

  1. new UDAFRegistration(session: Session)

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @HotSpotIntrinsicCandidate() @native()
  6. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  7. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  8. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @HotSpotIntrinsicCandidate() @native()
  9. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @HotSpotIntrinsicCandidate() @native()
  10. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  11. def log(): Logger
    Attributes
    protected[internal]
    Definition Classes
    Logging
  12. def logDebug(msg: String, throwable: Throwable): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  13. def logDebug(msg: String): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  14. def logError(msg: String, throwable: Throwable): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  15. def logError(msg: String): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  16. def logInfo(msg: String, throwable: Throwable): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  17. def logInfo(msg: String): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  18. def logTrace(msg: String, throwable: Throwable): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  19. def logTrace(msg: String): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  20. def logWarning(msg: String, throwable: Throwable): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  21. def logWarning(msg: String): Unit
    Attributes
    protected[internal]
    Definition Classes
    Logging
  22. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  23. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @HotSpotIntrinsicCandidate() @native()
  24. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @HotSpotIntrinsicCandidate() @native()
  25. def registerPermanent(funcName: String, udaf: JavaUDAF, stageLocation: String): AggregateFunction

    Registers a Java UDAF instance as a permanent UDAF.

    Registers a Java UDAF instance as a permanent UDAF.

    funcName

    The name of the UDAF.

    udaf

    The Java UDAF instance.

    stageLocation

    The stage location to upload JARs.

    returns

    An AggregateFunction representing the UDAF.

    Since

    1.19.0

  26. def registerPermanent(funcName: String, udaf: UDAF, stageLocation: String): AggregateFunction

    Registers a Scala UDAF instance as a permanent UDAF.

    Registers a Scala UDAF instance as a permanent UDAF.

    funcName

    The name of the UDAF.

    udaf

    The Scala UDAF instance to be registered.

    stageLocation

    The stage location to upload JARs.

    returns

    An AggregateFunction representing the UDAF.

    Since

    1.19.0

  27. def registerTemporary(funcName: String, udaf: JavaUDAF): AggregateFunction

    Registers a Java UDAF instance as a temporary UDAF.

    Registers a Java UDAF instance as a temporary UDAF.

    funcName

    The name of the UDAF.

    udaf

    The Java UDAF instance.

    returns

    An AggregateFunction representing the UDAF.

    Since

    1.19.0

  28. def registerTemporary(udaf: JavaUDAF): AggregateFunction

    Registers a Java UDAF instance as a temporary anonymous UDAF that is scoped to this session.

    Registers a Java UDAF instance as a temporary anonymous UDAF that is scoped to this session.

    udaf

    The Java UDAF instance.

    returns

    An AggregateFunction representing the UDAF.

    Since

    1.19.0

  29. def registerTemporary(funcName: String, udaf: UDAF): AggregateFunction

    Registers a Scala UDAF instance as a temporary UDAF.

    Registers a Scala UDAF instance as a temporary UDAF.

    funcName

    The name of the UDAF.

    udaf

    The Scala UDAF instance to be registered.

    returns

    An AggregateFunction representing the UDAF.

    Since

    1.19.0

  30. def registerTemporary(udaf: UDAF): AggregateFunction

    Registers a Scala UDAF instance as a temporary anonymous UDAF that is scoped to this session.

    Registers a Scala UDAF instance as a temporary anonymous UDAF that is scoped to this session.

    udaf

    The Scala UDAF instance to be registered.

    returns

    An AggregateFunction representing the UDAF.

    Since

    1.19.0

  31. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  32. def toString(): String
    Definition Classes
    AnyRef → Any
  33. def udaf(funcName: String, execName: String = "", execFilePath: String = "")(func: => AggregateFunction): AggregateFunction
    Attributes
    protected
    Annotations
    @inline()
  34. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  35. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()
  36. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])

Deprecated Value Members

  1. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable]) @Deprecated
    Deprecated

    (Since version 9)

Inherited from Logging

Inherited from AnyRef

Inherited from Any

Ungrouped