diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/commands/expressions/FunctionInvocation.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/commands/expressions/FunctionInvocation.scala index 855876b2c8f11..4ddd899b5823b 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/commands/expressions/FunctionInvocation.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/commands/expressions/FunctionInvocation.scala @@ -20,7 +20,6 @@ package org.neo4j.cypher.internal.compiler.v3_1.commands.expressions import org.neo4j.cypher.internal.compiler.v3_1._ -import org.neo4j.cypher.internal.compiler.v3_1.executionplan.ProcedureCallMode import org.neo4j.cypher.internal.compiler.v3_1.helpers.{RuntimeJavaValueConverter, RuntimeScalaValueConverter} import org.neo4j.cypher.internal.compiler.v3_1.mutation.GraphElementPropertyFunctions import org.neo4j.cypher.internal.compiler.v3_1.pipes.QueryState @@ -30,8 +29,6 @@ import org.neo4j.cypher.internal.compiler.v3_1.symbols.SymbolTable case class FunctionInvocation(signature: UserFunctionSignature, arguments: IndexedSeq[Expression]) extends Expression with GraphElementPropertyFunctions { - private val callMode = ProcedureCallMode.fromAccessMode(signature.accessMode) - override def apply(ctx: ExecutionContext)(implicit state: QueryState): Any = { val query = state.query @@ -39,7 +36,8 @@ case class FunctionInvocation(signature: UserFunctionSignature, arguments: Index val converter = new RuntimeJavaValueConverter(state.query.isGraphKernelResultValue, state.typeConverter.asPublicType) val scalaValues = new RuntimeScalaValueConverter(isGraphKernelResultValue, state.typeConverter.asPrivateType) val argValues = arguments.map(arg => converter.asDeepJavaValue(arg(ctx)(state))) - val result = callMode.callFunction(query, signature.name, argValues) + + val result = query.callFunction(signature.name, argValues, signature.allowed) scalaValues.asDeepScalaValue(result) } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/executionplan/ProcedureCallMode.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/executionplan/ProcedureCallMode.scala index 597366c27838e..1ec92d02447e6 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/executionplan/ProcedureCallMode.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/executionplan/ProcedureCallMode.scala @@ -36,8 +36,6 @@ sealed trait ProcedureCallMode { def callProcedure(ctx: QueryContext, name: QualifiedName, args: Seq[Any]): Iterator[Array[AnyRef]] - def callFunction(ctx: QueryContext, name: QualifiedName, args: Seq[Any]): AnyRef - val allowed: Array[String] } @@ -46,9 +44,6 @@ case class LazyReadOnlyCallMode(allowed: Array[String]) extends ProcedureCallMod override def callProcedure(ctx: QueryContext, name: QualifiedName, args: Seq[Any]): Iterator[Array[AnyRef]] = ctx.callReadOnlyProcedure(name, args, allowed) - - override def callFunction(ctx: QueryContext, name: QualifiedName, args: Seq[Any]) = - ctx.callReadOnlyFunction(name, args, allowed) } case class EagerReadWriteCallMode(allowed: Array[String]) extends ProcedureCallMode { @@ -62,9 +57,6 @@ case class EagerReadWriteCallMode(allowed: Array[String]) extends ProcedureCallM } builder.result().iterator } - - override def callFunction(ctx: QueryContext, name: QualifiedName, args: Seq[Any]) = - ctx.callReadWriteFunction(name, args, allowed) } case class SchemaWriteCallMode(allowed: Array[String]) extends ProcedureCallMode { @@ -78,9 +70,6 @@ case class SchemaWriteCallMode(allowed: Array[String]) extends ProcedureCallMode } builder.result().iterator } - - override def callFunction(ctx: QueryContext, name: QualifiedName, args: Seq[Any]) = - ctx.callSchemaWriteFunction(name, args, allowed) } case class DbmsCallMode(allowed: Array[String]) extends ProcedureCallMode { @@ -94,7 +83,4 @@ case class DbmsCallMode(allowed: Array[String]) extends ProcedureCallMode { } builder.result().iterator } - - override def callFunction(ctx: QueryContext, name: QualifiedName, args: Seq[Any]) = - ctx.callDbmsFunction(name, args, allowed) } diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/DelegatingQueryContext.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/DelegatingQueryContext.scala index de0f354b7412e..b5721aa8bc9dd 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/DelegatingQueryContext.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/DelegatingQueryContext.scala @@ -193,17 +193,8 @@ class DelegatingQueryContext(val inner: QueryContext) extends QueryContext { override def callDbmsProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = inner.callDbmsProcedure(name, args, allowed) - override def callReadOnlyFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - singleDbHit(inner.callReadOnlyFunction(name, args, allowed)) - - override def callReadWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - singleDbHit(inner.callReadWriteFunction(name, args, allowed)) - - override def callSchemaWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - singleDbHit(inner.callSchemaWriteFunction(name, args, allowed)) - - override def callDbmsFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - inner.callDbmsFunction(name, args, allowed) + override def callFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = + singleDbHit(inner.callFunction(name, args, allowed)) override def isGraphKernelResultValue(v: Any): Boolean = inner.isGraphKernelResultValue(v) diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/ProcedureSignature.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/ProcedureSignature.scala index b0cb67de7c59b..7aa63d562d17c 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/ProcedureSignature.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/ProcedureSignature.scala @@ -37,7 +37,7 @@ case class UserFunctionSignature(name: QualifiedName, inputSignature: IndexedSeq[FieldSignature], outputType: CypherType, deprecationInfo: Option[String], - accessMode: ProcedureReadOnlyAccess) + allowed: Array[String]) object QualifiedName { def apply(unresolved: UnresolvedCall): QualifiedName = diff --git a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContext.scala b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContext.scala index 5d6a7be00ef03..61dffc7036f02 100644 --- a/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContext.scala +++ b/community/cypher/cypher-compiler-3.1/src/main/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContext.scala @@ -164,12 +164,7 @@ trait QueryContext extends TokenContext { def callDbmsProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]): Iterator[Array[AnyRef]] - def callReadOnlyFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef - - def callReadWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef - def callSchemaWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef - - def callDbmsFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef + def callFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef // Check if a runtime value is a node, relationship, path or some such value returned from // other query context values by calling down to the underlying database diff --git a/community/cypher/cypher-compiler-3.1/src/test/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContextAdaptation.scala b/community/cypher/cypher-compiler-3.1/src/test/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContextAdaptation.scala index b9c588943603c..578121f6aace0 100644 --- a/community/cypher/cypher-compiler-3.1/src/test/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContextAdaptation.scala +++ b/community/cypher/cypher-compiler-3.1/src/test/scala/org/neo4j/cypher/internal/compiler/v3_1/spi/QueryContextAdaptation.scala @@ -130,14 +130,7 @@ trait QueryContextAdaptation { override def callDbmsProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]): Iterator[Array[AnyRef]] = ??? - override def callReadOnlyFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef = ??? - - override def callDbmsFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef = ??? - - override def callSchemaWriteFunction(name: QualifiedName, args: Seq[Any], - allowed: Array[String]): AnyRef = ??? - - override def callReadWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef = ??? + override def callFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]): AnyRef = ??? override def getOrCreateFromSchemaState[K, V](key: K, creator: => V): V = ??? diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/ExceptionTranslatingQueryContextFor3_1.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/ExceptionTranslatingQueryContextFor3_1.scala index 9bfd17933ad28..5ec10f37d1672 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/ExceptionTranslatingQueryContextFor3_1.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/ExceptionTranslatingQueryContextFor3_1.scala @@ -141,17 +141,8 @@ class ExceptionTranslatingQueryContextFor3_1(val inner: QueryContext) extends Qu override def callDbmsProcedure(name: QualifiedName, args: Seq[Any], allowed: Array[String]): Iterator[Array[AnyRef]] = translateIterator(inner.callDbmsProcedure(name, args, allowed)) - override def callReadOnlyFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - translateException(inner.callReadOnlyFunction(name, args, allowed)) - - override def callReadWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - translateException(inner.callReadWriteFunction(name, args, allowed)) - - override def callSchemaWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - translateException(inner.callSchemaWriteFunction(name, args, allowed)) - - override def callDbmsFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = - translateException(inner.callDbmsFunction(name, args, allowed)) + override def callFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = + translateException(inner.callFunction(name, args, allowed)) override def isGraphKernelResultValue(v: Any): Boolean = translateException(inner.isGraphKernelResultValue(v)) diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundPlanContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundPlanContext.scala index b952f3425311b..9c816752ec701 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundPlanContext.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundPlanContext.scala @@ -151,7 +151,7 @@ class TransactionBoundPlanContext(tc: TransactionalContextWrapperv3_1) val output = asCypherType(ks.outputType()) val deprecationInfo = asOption(ks.deprecated()) - Some(UserFunctionSignature(name, input, output, deprecationInfo, ProcedureReadOnlyAccess(ks.allowed()))) + Some(UserFunctionSignature(name, input, output, deprecationInfo, ks.allowed())) } else None } diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala index 4786f58594ba0..1bf3541880aac 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_1/TransactionBoundQueryContext.scala @@ -636,36 +636,13 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional } } - override def callReadOnlyFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = { + override def callFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = { val revertable = transactionalContext.accessMode match { case a: AuthSubject if a.allowsProcedureWith(allowed) => Some(transactionalContext.restrictCurrentTransaction(AccessMode.Static.OVERRIDE_READ)) case _ => None } - callFunction(name, args, transactionalContext.statement.readOperations().functionCallRead, revertable.foreach(_.close)) - } - - override def callReadWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = { - val revertable = transactionalContext.accessMode match { - case a: AuthSubject if a.allowsProcedureWith(allowed) => - Some(transactionalContext.restrictCurrentTransaction(AccessMode.Static.OVERRIDE_WRITE)) - case _ => None - } - callFunction(name, args, transactionalContext.statement.dataWriteOperations().functionCallWrite, - revertable.foreach(_.close)) - } - - override def callSchemaWriteFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = { - val revertable = transactionalContext.accessMode match { - case a: AuthSubject if a.allowsProcedureWith(allowed) => - Some(transactionalContext.restrictCurrentTransaction(AccessMode.Static.OVERRIDE_SCHEMA)) - case _ => None - } - callFunction(name, args, transactionalContext.statement.schemaWriteOperations().functionCallSchema, revertable.foreach(_.close)) - } - - override def callDbmsFunction(name: QualifiedName, args: Seq[Any], allowed: Array[String]) = { - callFunction(name, args, transactionalContext.dbmsOperations.functionCallDbms, ()) + callFunction(name, args, transactionalContext.statement.readOperations().functionCall, revertable.foreach(_.close)) } private def callFunction(name: QualifiedName, args: Seq[Any], diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/DataWriteOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/api/DataWriteOperations.java index 3b540d3bed94d..26ce12347bd2d 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/DataWriteOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/DataWriteOperations.java @@ -151,6 +151,4 @@ void relationshipRemoveFromLegacyIndex( String indexName, long relationship ) /** Invoke a read/write procedure by name */ RawIterator procedureCallWrite( QualifiedName name, Object[] input ) throws ProcedureException; - - Object functionCallWrite( QualifiedName name, Object[] input ) throws ProcedureException; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java index 260a0e3ee11e6..8cc2f255dbf26 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/ReadOperations.java @@ -567,5 +567,5 @@ DoubleLongRegister indexSample( IndexDescriptor index, DoubleLongRegister target RawIterator procedureCallRead( QualifiedName name, Object[] input ) throws ProcedureException; /** Invoke a read-only procedure by name */ - Object functionCallRead( QualifiedName name, Object[] input ) throws ProcedureException; + Object functionCall( QualifiedName name, Object[] input ) throws ProcedureException; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/SchemaWriteOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/api/SchemaWriteOperations.java index a522c03cc91cd..d8de9284c8225 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/SchemaWriteOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/SchemaWriteOperations.java @@ -67,6 +67,4 @@ RelationshipPropertyExistenceConstraint relationshipPropertyExistenceConstraintC /** Invoke a schema procedure by name */ RawIterator procedureCallSchema( QualifiedName name, Object[] input ) throws ProcedureException; - - Object functionCallSchema( QualifiedName name, Object[] input ) throws ProcedureException; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java index bf38e25615666..c61bd131edcee 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/OperationsFacade.java @@ -558,9 +558,9 @@ public Optional functionGet( QualifiedName name ) } @Override - public Object functionCallRead( QualifiedName name, Object[] input ) throws ProcedureException + public Object functionCall( QualifiedName name, Object[] input ) throws ProcedureException { - return callFunction( name, input, AccessMode.Static.READ ); + return callFunction( name, input ); } @Override @@ -1089,12 +1089,6 @@ public RawIterator procedureCallWrite( QualifiedNa return callProcedure( name, input, AccessMode.Static.FULL ); } - @Override - public Object functionCallWrite( QualifiedName name, Object[] input ) throws ProcedureException - { - // FIXME: should this be AccessMode.Static.WRITE instead? - return callFunction( name, input, AccessMode.Static.FULL ); - } // // @@ -1165,12 +1159,6 @@ public RawIterator procedureCallSchema( QualifiedN return callProcedure( name, input, AccessMode.Static.FULL ); } - @Override - public Object functionCallSchema( QualifiedName name, Object[] input ) throws ProcedureException - { - return callFunction( name, input, AccessMode.Static.FULL ); - } - // // @@ -1511,7 +1499,7 @@ private RawIterator callProcedure( { statement.assertOpen(); - try ( KernelTransaction.Revertable revertable = tx.overrideWith( mode ) ) + try ( KernelTransaction.Revertable ignore = tx.overrideWith( mode ) ) { BasicContext ctx = new BasicContext(); ctx.put( Context.KERNEL_TRANSACTION, tx ); @@ -1521,12 +1509,12 @@ private RawIterator callProcedure( } private Object callFunction( - QualifiedName name, Object[] input, AccessMode mode ) + QualifiedName name, Object[] input ) throws ProcedureException { statement.assertOpen(); - try ( KernelTransaction.Revertable revertable = tx.overrideWith( mode ) ) + try ( KernelTransaction.Revertable ignore = tx.overrideWith( AccessMode.Static.READ ) ) { BasicContext ctx = new BasicContext(); ctx.put( Context.KERNEL_TRANSACTION, tx ); diff --git a/community/kernel/src/main/java/org/neo4j/procedure/UserFunction.java b/community/kernel/src/main/java/org/neo4j/procedure/UserFunction.java index 1779fe2929d68..0555b6addfc47 100644 --- a/community/kernel/src/main/java/org/neo4j/procedure/UserFunction.java +++ b/community/kernel/src/main/java/org/neo4j/procedure/UserFunction.java @@ -29,13 +29,9 @@ * cypher query language. *

* Functions accept input, use that input to perform work, and then return a value. The work performed usually - * involves one or more resources, such as a {@link org.neo4j.graphdb.GraphDatabaseService}. + * involves one or more resources, such as a {@link org.neo4j.graphdb.GraphDatabaseService}. Functions are read-only, i.e + * can't update neither the graph nor update schema. *

- * A function is associated with one of the following modes - * READ allows only reading the graph (default mode) - * WRITE allows reading and writing the graph - * SCHEMA allows reading the graphs and performing schema operations - * DBMS allows managing the database (i.e. change password) * *

Input declaration

* A function can accept input arguments, which is defined in the arguments to the