# Manage user-defined functions

User-defined functions (UDFs) are programs that you write in Lua to augment basic features of the Aerospike Database, such as aggregating or modifying data. You can use Aerospike Quick Look (AQL) to register, list, describe, run, and remove UDFs from the Aerospike server.

## REGISTER MODULE

You must register UDFs with the system with the `REGISTER MODULE` command. The command uploads the file at the given path `<FILE_PATH>`.

```text
REGISTER MODULE '<FILE_PATH>'
```

The name of the file and the module are the same. For example:

Example: Register a UDF

```text
REGISTER MODULE 'udf/testudf.lua'

OK, 1 module added.
```

When you register a module, the module is automatically copied to all nodes in the cluster. If you can run the module from one cluster node but not another, verify the following:

-   The cluster is healthy
-   The user that runs Aerospike also owns `/opt/aerospike/smd/*`

## EXECUTE

Once you register a UDF module, use the UDFs it contains with one of the following command formats:

```plaintext
EXECUTE <module>.<function>(<args>) ON <ns>[.<set>]

EXECUTE <module>.<function>(<args>) ON <ns>[.<set>] WHERE PK = <key>

EXECUTE <module>.<function>(<args>) ON <ns>[.<set>] WHERE <bin> = <value>

EXECUTE <module>.<function>(<args>) ON <ns>[.<set>] WHERE <bin> BETWEEN <lower> AND <upper>
```

The command formats contain the following arguments:

-   `module` : UDF module containing the function to invoke.
-   `function` : UDF to invoke.
-   `args` : Comma-separated list of argument values for the UDF.
-   `ns` : Namespace for the records to be queried.
-   `set` : Name of the set for the record to be queried.
-   `key` : Record’s primary key.
-   `bin` : Name of a bin.
-   `value` : Value of a bin.
-   `lower` : Lower bound for a numeric range query.
-   `upper` : Upper bound for a numeric range query.

The following is an example of invoking the UDF `udf1` from the module `myudfs.lua`. The `udf1` function returns the value of bin `bar` on the record in namespace `test`, set `demo` with the primary key `key1`.

Example: Invoke UDF

```text
select * from test.demo

+--------+-----+--------+------+

| PK     | foo | bar    | baz  |

+--------+-----+--------+------+

| "key1" | 123 | "abc"  | true |

| "key2" | 24  |        |      |

| "key3" | 123 | "abcd" | true |

+--------+-----+--------+------+

3 rows in set (0.012 secs)

EXECUTE myudfs.udf1('bar') ON test.demo WHERE PK = "key1"

+-------+

| udf1  |

+-------+

| "abc" |

+-------+
```

To also use UDFs as streams with aggregation queries, see [Manage Records](https://aerospike.com/docs/database/tools/aql/records#aggregate).

## SHOW MODULES

To list UDFs that are already registered in your cluster, enter the following command:

```plaintext
SHOW MODULES
```

The output shows the filename of the module, its type, which is `"lua"`, and a hash for each module.

Example: List UDFs

```text
SHOW MODULES

+---------------------------+-------+------------------------+

| module                    | type  | hash                   |

+---------------------------+-------+------------------------+

| "example1.lua"            | "lua" | "033671e05067888fce09" |

| "example2.lua"            | "lua" | "07b42082cca8e73a96b2" |

+---------------------------+-------+------------------------+

2 rows in set (0.000 secs)
```

The module information includes the following:

-   Module name and type (currently, only Lua is supported)
-   Hash value of the file. Use the hash value to verify the version or instance of a UDF on the server.

## DESC MODULE

To read the contents of a registered UDF, enter the following command:

```plaintext
DESC MODULE <module>
```

This command describes the UDF module named `<module>`.

This example output includes the following:

-   `gen`: Hash value for the UDF.
-   `type`: Module type.
-   `content`: Text of the entire UDF.
-   `output`: Readable content of the UDF. In this example, output is set to `raw`.

Example: Output for a registered UDF

```text
set output raw

OUTPUT = RAW

desc module example2.lua

*************************** 1. row ***************************

content: "

local function bin(name)

    local function x(rec)

        return rec[name]

    end

    return x

end

local function even(a)

    return a % 2 == 0

end

local function add(a,b)

    return a + b

end

local function multiplier(factor)

    local function x(a)

        return a * factor

    end

    return x

end

function foo(rec)

    return bin("a")(rec)

end

function a(stream)

    return stream : map(bin("a"))

end

function even_a(stream)

    return stream : map(bin("a")) : filter(even)

end

function sum_even_a(stream)

    return stream : map(bin("a")) : filter(even) : reduce(add)

end

function sum_even_a_x(stream, factor)

    return stream : map(bin("a")) : filter(even) : reduce(add) : map(multiplier(factor))

end"

gen: "13fgxKWlQDHukDDp0/fsrjxvcMA="

type: "LUA"

[127.0.0.1:3000] 1 row in set (0.011 secs)
```

## REMOVE MODULE

To completely delete a UDF module from the system, use `REMOVE MODULE`.

Example: Remove a registered UDF

```text
REMOVE MODULE example2.lua
```