cancel
Showing results for 
Search instead for 
Did you mean: 

How to define a VOID custom procedure with side effects?

benjamin_rood
Node Clone

I am having a bit of difficulty knowing how to define a procedure using apoc.custom.declareProcedure / apoc.custom.asProcedure that modifies a node and returns nothing (void):

 

CALL apoc.custom.declareProcedure(
  'updateNodeMetadata(node::NODE) :: VOID',
  'WITH datetime.realtime() AS now, $node AS node, $node.objectVersion AS oldVersion
  SET node.lastChangedAt = now
  SET node.objectVersion = CASE WHEN oldVersion IS NULL THEN 1 ELSE oldVersion + 1 END',
  'write');

 

I want to take a node as an argument, and modify a couple of metadata fields on the node.

When I look at the logs for why this fails, the logs say the following, but the function *is* defined as VOID already?

 

022-08-10 11:30:25.579+0000 ERROR [a.c.CypherProcedures] [neo4j] Could not register procedure: custom.updateNodeMetadata with WITH datetime.realtime() AS now, $node AS node, $node.objectVersion AS oldVersion
  SET node.lastChangedAt = now
  SET node.objectVersion = CASE WHEN oldVersion IS NULL THEN 1 ELSE oldVersion + 1 END RETURN
 accepting[node = null :: NODE?] resulting in [] mode WRITE Procedures with zero output fields must be declared as VOID
org.neo4j.internal.kernel.api.exceptions.ProcedureException: Procedures with zero output fields must be declared as VOID

 

 

1 ACCEPTED SOLUTION

glilienfield
Ninja
Ninja

 I took your code as is and pasted it into my desktop and it worked.  I am using APOC 4.4.0.8.  

View solution in original post

3 REPLIES 3

benjamin_rood
Node Clone

It works if I use apoc.custom.asProcedure like this:

 

 

 

CALL apoc.custom.asProcedure(
  'updateNodeMetadata',
  'WITH datetime.realtime() AS now, $node AS node, $node.objectVersion AS oldVersion
  SET node.lastChangedAt = now
  SET node.objectVersion = CASE WHEN oldVersion IS NULL THEN 1 ELSE oldVersion + 1 END',
  'write', [['value', 'VOID']],
  [['node', 'NODE']], "")

 

 

But I should say that the problem with this of course, is that you still need to YIELD the result, even though it's NULL, which is annoying.

If I define it as a function, this is the best I can get:

CALL apoc.custom.declareFunction(
  'unm(node::NODE) :: MAP',
  'WITH datetime.realtime() AS now, $node AS node, $node.objectVersion AS oldVersion
  SET node.lastChangedAt = now
  SET node.objectVersion = CASE WHEN oldVersion IS NULL THEN 1 ELSE oldVersion + 1 END
  RETURN NULL')

 

 

But  this is not callable unless the database user is an admin:

ERROR: Neo.ClientError.Security.Forbidden
Write operations are not allowed for user 'neo4j' with roles [admin] restricted to READ.

glilienfield
Ninja
Ninja

 I took your code as is and pasted it into my desktop and it worked.  I am using APOC 4.4.0.8.  

Ah, okay, our cluster is still stuck on 4.0.x

Supplemental question: Any way of CALL-ing a VOID procedure and skipping the YIELD step?