Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NOID] Fixes #3401: APOC Custom Procedures/Function new procedures working with Cluster (#3943) #4030

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.custom/apoc.custom.list.adoc[apoc.custom.list icon:book[]] +

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.custom/apoc.custom.list.adoc[apoc.custom.list icon:book[]] +

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.custom/apoc.custom.list.adoc[apoc.custom.list icon:book[]] +

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.custom/apoc.custom.list.adoc[apoc.custom.list icon:book[]] +

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.custom/apoc.custom.list.adoc[apoc.custom.list icon:book[]] +

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.custom/apoc.custom.list.adoc[apoc.custom.list icon:book[]] +

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,44 @@



I wanted for a long time to be able to register Cypher statements as proper procedures and functions, so that they become callable in a standalone way.
include::partial$systemdbonly.note.adoc[]

You can achieve that with the `apoc.custom.declareProcedure` and `apoc.custom.declareFunction` procedure calls.
Those register a given Cypher statement, prefixed with the `custom.*` namespace, overriding potentially existing ones, so you can redefine them as needed.
[WARNING]
====
Installing, updating or removing a custom Cypher statement is an eventually consistent operation.
Therefore, they are not immediately added/updated/removed,
but they have a refresh rate handled by the Apoc configuration `apoc.custom.procedures.refresh=<MILLISECONDS>`.

In case of a cluster environment,
the `apoc.custom.procedures.refresh` also replicate the procedures/functions to each cluster member.
====

.Available procedures
[separator=¦,opts=header,cols="5,1m,1m"]
|===
¦Qualified Name¦Type¦Release
include::example$generated-documentation/apoc.custom.dropAll.adoc[]
include::example$generated-documentation/apoc.custom.dropFunction.adoc[]
include::example$generated-documentation/apoc.custom.dropProcedure.adoc[]
include::example$generated-documentation/apoc.custom.installFunction.adoc[]
include::example$generated-documentation/apoc.custom.installProcedure.adoc[]
include::example$generated-documentation/apoc.custom.list.adoc[]
include::example$generated-documentation/apoc.custom.show.adoc[]
|===


== Overview

NOTE: APOC provides also xref::overview/apoc.custom/apoc.custom.asFunction.adoc[apoc.custom.asFunction] and xref::overview/apoc.custom/apoc.custom.asProcedure.adoc[apoc.custom.asProcedure] procedures,
but they have been deprecated in favor of `apoc.custom.declare*`s.
I wanted for a long time to be able to register Cypher statements as proper procedures and functions, so that they become callable in a standalone way.

You can achieve that with the `apoc.custom.installProcedure` and `apoc.custom.installFunction` procedure calls.
Those register a given Cypher statement, prefixed with the `custom.*` namespace, overriding potentially existing ones, so you can redefine them as needed.

The first parameter of the `apoc.custom.declareProcedure` and `apoc.custom.declareFunction` procedures,
The first parameter of the `apoc.custom.installProcedure` and `apoc.custom.installFunction` procedures,
is the signature of the procedure/function you want to create.
This looks similar to the `signature` results returned by the `SHOW PROCEDURES YIELD signature` and `SHOW FUNCTIONS YIELD signature` cypher commands,
that is:

This looks similar to the `signature` results returned by the `SHOW PROCEDURES YIELD signature`, `SHOW FUNCTIONS YIELD signature` cypher commands, or by the `CALL apoc.help('<fun_or_procedure_name>') YIELD signature` procedure, just without the `?`.
That is:
- for a procedure: `nameProcedure(firstParam = defaultValue :: typeParam , secondParam = defaultValue :: typeParam, ....) :: (firstResult :: typeResult, secondResult :: typeResult, ... )`
- for a function: `nameFunction(firstParam = defaultValue :: typeParam , secondParam = defaultValue :: typeParam, ....) :: typeResult`

Expand Down Expand Up @@ -49,9 +74,9 @@ The type names are what you would expect and see in outputs of `dbms.procedures`
The default values are parsed as JSON.

.Type Names
The `typeParam` and `typeResult` in the signature parameter are what you would expect to see in outputs of `SHOW PROCEDURES`, `SHOW FUNCTIONS` or `CALL apoc.help('')`, just without the final `?`.
The following values are supported:
* FLOAT, DOUBLE, INT, INTEGER, NUMBER, LONG
The `typeParam` and `typeResult` in the signature parameter can be one of the following values:

* FLOAT, DOUBLE, INT, INTEGER, INTEGER | FLOAT, NUMBER, LONG
* TEXT, STRING
* BOOL, BOOLEAN
* POINT, GEO, GEOMETRY
Expand All @@ -66,21 +91,24 @@ The following values are supported:
NOTE: If you override procedures or functions you might need to call `call db.clearQueryCaches()` as lookups to internal id's are kept in compiled query plans.


== Custom Procedures with `apoc.custom.declareProcedure`
The following examples assume that we are on the `neo4j` database,
and we want to create the custom procedures/function in that database.

== Custom Procedures with `apoc.custom.installProcedure`

include::partial$usage/apoc.custom.declareProcedure.adoc[]
include::partial$usage/apoc.custom.installProcedure.adoc[]

== Custom Functions with `apoc.custom.declareFunction`
== Custom Functions with `apoc.custom.installFunction`

include::partial$usage/apoc.custom.declareFunction.adoc[]
include::partial$usage/apoc.custom.installFunction.adoc[]


== List of registered procedures/function with `apoc.custom.list`

The procedure `apoc.custom.list` provide a list of all registered procedures/function via
`apoc.custom.declareProcedure` and `apoc.custom.declareFunction`, `apoc.custom.asProcedure` and `apoc.custom.asFunction`.
The procedure `apoc.custom.list` provide a list of all registered procedures/function via
`apoc.custom.installProcedure` and `apoc.custom.installFunction`

Given the this call:
Given this call:

[source,cypher]
----
Expand All @@ -92,21 +120,22 @@ The output will look like the following table:
[%autowidth,opts=header]
|===
| type | name | description | mode | statement | inputs | outputs | forceSingle
| "function" | "answer" | <null> | <null> | "RETURN $input as answer" | [["input","number"]] | "long" | false
| "procedure" | "answer" | "Procedure that answer to the Ultimate Question of Life, the Universe, and Everything" | "read" | "RETURN $input as answer" | [["input","int","42"]] | [["answer","number"]] | <null>
| "function" | "answer" | <null> | <null> | "RETURN $input as answer" | [["input","integer \| float"]] | "long" | false
| "procedure" | "answer" | "Procedure that answer to the Ultimate Question of Life, the Universe, and Everything" | "read" | "RETURN $input as answer" | [["input","int","42"]] | [["answer","integer \| float"]] | <null>
|===


== Remove a procedure `apoc.custom.removeProcedure`
== Remove a procedure `apoc.custom.dropProcedure`

The procedure `apoc.custom.removeProcedure` allows to delete the targeted custom procedure.
The procedure `apoc.custom.dropProcedure` allows to delete the targeted custom procedure, from a specific database (with `neo4j` as a default),
*after a time defined by the configuration `apoc.custom.procedures.refresh`*.


Given the this call:
Given this call:

[source,cypher]
----
CALL apoc.custom.removeProcedure(<name>)
CALL apoc.custom.dropProcedure(<name>, <databaseName>)
----

Fields:
Expand All @@ -115,19 +144,21 @@ Fields:
|===
| argument | description
| name | the procedure name
| databaseName | the database name (default: `neo4j`)
|===


== Remove a procedure `apoc.custom.removeFunction`
== Remove a procedure `apoc.custom.dropFunction`

The procedure `apoc.custom.removeFunction` allows to delete the targeted custom function.
The procedure `apoc.custom.dropFunction` allows to delete the targeted custom function, from a specific database (with `neo4j` as a default),
*after a time defined by the configuration `apoc.custom.procedures.refresh`*.


Given the this call:
Given this call:

[source,cypher]
----
CALL apoc.custom.removeFunction(<name>)
CALL apoc.custom.dropFunction(<name>)
----

Fields:
Expand All @@ -136,19 +167,10 @@ Fields:
|===
| argument | description
| name | the function name
| databaseName | the database name (default: `neo4j`)
|===


== How to manage procedure/function replication in a Causal Cluster

In order to replicate the procedure/function in a cluster environment you can tune the following parameters:

[%autowidth,opts=header]
|===
| name | type | description
| `apoc.custom.procedures.refresh` | long (default `60000`) | the refresh time that allows replicating the procedure/function
changes to each cluster member
|===

=== Export metadata

Expand Down
Loading
Loading