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

Fixes #3401: APOC Custom Procedures/Function new procedures working with Cluster #3943

Merged
merged 3 commits into from
Feb 22, 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,15 +5,42 @@



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

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.

The first parameter of the `apoc.custom.declareProcedure` and `apoc.custom.declareFunction` procedures,
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.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`, `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, ... )`
Expand Down Expand Up @@ -45,28 +72,31 @@ NOTE: If you override procedures or functions you might need to call `call db.cl

[NOTE]
====
Starting from version 5.11, if we execute a `CALL apoc.custom.declareFunction('nameFun(....)')`, or a `CALL apoc.custom.declareProcedure('nameProc(....)')`,
Starting from version 5.11, if we execute a `CALL apoc.custom.installFunction('nameFun(....)')`, or a `CALL apoc.custom.installProcedure('nameProc(....)')`,
we cannot execute respectively a `RETURN custom.nameFun(..)` or a `CALL custom.nameProc()` within the same transaction, an error will be thrown.

So we must necessarily open a new transaction to execute the custom procedures / functions declared.
====


== 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.

include::partial$usage/apoc.custom.declareProcedure.adoc[]
== Custom Procedures with `apoc.custom.installProcedure`

== Custom Functions with `apoc.custom.declareFunction`
include::partial$usage/apoc.custom.installProcedure.adoc[]

include::partial$usage/apoc.custom.declareFunction.adoc[]
== Custom Functions with `apoc.custom.installFunction`

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.installProcedure` and `apoc.custom.installFunction`

Given the this call:
Given this call:

[source,cypher]
----
Expand All @@ -83,16 +113,17 @@ The output will look like the following table:
|===


== 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 @@ -101,19 +132,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 @@ -122,19 +155,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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,59 @@ This chapter lists all the features that have been removed, deprecated, added or
|===
| Feature
| Details

a|
label:procedure[]
[source, cypher, role="noheader"]
----
apoc.custom.declareFunction
----
a|
Replaced by:
[source, cypher, role="noheader"]
----
apoc.custom.installFunction
----

a|
label:procedure[]
[source, cypher, role="noheader"]
----
apoc.custom.declareProcedure
----
a|
Replaced by:
[source, cypher, role="noheader"]
----
apoc.custom.installProcedure
----

a|
label:procedure[]
[source, cypher, role="noheader"]
----
apoc.custom.removeFunction
----
a|
Replaced by:
[source, cypher, role="noheader"]
----
apoc.custom.dropFunction
----

a|
label:procedure[]
[source, cypher, role="noheader"]
----
apoc.custom.removeProcedure
----
a|
Replaced by:
[source, cypher, role="noheader"]
----
apoc.custom.dropProcedure
----

a|
label:function[]
label:deprecated[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This file is generated by DocsTest, so don't change it!
= apoc.custom.declareFunction
:description: This section contains reference documentation for the apoc.custom.declareFunction procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-extended[] label:deprecated[]

[.emphasis]
apoc.custom.declareFunction(signature, statement, forceSingle, description) - register a custom cypher function
Expand All @@ -20,6 +20,8 @@ apoc.custom.declareFunction(signature :: STRING?, statement :: STRING?, forceSin
[WARNING]
====
This procedure is not intended to be used in a cluster environment, and may act unpredictably.

xref:cypher-execution/cypher-based-procedures-functions.adoc[Use these non-deprecated procedures instead, which work with clusters]
====

== Input parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This file is generated by DocsTest, so don't change it!
= apoc.custom.declareProcedure
:description: This section contains reference documentation for the apoc.custom.declareProcedure procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-extended[] label:deprecated[]

[.emphasis]
apoc.custom.declareProcedure(signature, statement, mode, description) - register a custom cypher procedure
Expand All @@ -20,6 +20,8 @@ apoc.custom.declareProcedure(signature :: STRING?, statement :: STRING?, mode =
[WARNING]
====
This procedure is not intended to be used in a cluster environment, and may act unpredictably.

xref:cypher-execution/cypher-based-procedures-functions.adoc[Use these non-deprecated procedures instead, which work with clusters]
====

== Input parameters
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

= apoc.custom.dropAll
:description: This section contains reference documentation for the apoc.custom.dropAll procedure.

label:procedure[] label:apoc-extended[]

[.emphasis]
Eventually drops all previously added custom procedures/functions and returns info

== Signature

[source]
----
apoc.custom.dropAll(databaseName = neo4j :: STRING?) :: (type :: STRING?, name :: STRING?, description :: STRING?, mode :: STRING?, statement :: STRING?, inputs :: LIST? OF LIST? OF STRING?, outputs :: ANY?, forceSingle :: BOOLEAN?)
----

== Input parameters
[.procedures, opts=header]
|===
| Name | Type | Default
|databaseName|STRING?|neo4j
|===


== Output parameters
[.procedures, opts=header]
|===
| Name | Type
|type|STRING?
|name|STRING?
|description|STRING?
|mode|STRING?
|statement|STRING?
|inputs|LIST? OF LIST? OF STRING?
|outputs|ANY?
|forceSingle|BOOLEAN?
|===

xref:cypher-execution/cypher-based-procedures-functions.adoc[More documentation of apoc.custom.dropAll,role=more information]

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

= apoc.custom.dropFunction
:description: This section contains reference documentation for the apoc.custom.dropFunction procedure.

label:procedure[] label:apoc-extended[]

[.emphasis]
Eventually drops the targeted custom function

== Signature

[source]
----
apoc.custom.dropFunction(name :: STRING?, databaseName = neo4j :: STRING?) :: VOID
----


== Input parameters
[.procedures, opts=header]
|===
| Name | Type | Default
|name|STRING?|null
|databaseName|STRING?|neo4j
|===

xref:cypher-execution/cypher-based-procedures-functions.adoc[More documentation of apoc.custom.dropFunction,role=more information]

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

= apoc.custom.dropProcedure
:description: This section contains reference documentation for the apoc.custom.dropProcedure procedure.

label:procedure[] label:apoc-extended[]

[.emphasis]
Eventually drops the targeted custom procedure

== Signature

[source]
----
apoc.custom.dropProcedure(name :: STRING?, databaseName = neo4j :: STRING?) :: VOID
----


== Input parameters
[.procedures, opts=header]
|===
| Name | Type | Default
|name|STRING?|null
|databaseName|STRING?|neo4j
|===


xref:cypher-execution/cypher-based-procedures-functions.adoc[More documentation of apoc.custom.dropFunction,role=more information]

Loading
Loading