Skip to content

Commit

Permalink
Changed functions to be read-only
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Sep 9, 2016
1 parent 7b5ea12 commit 905ba2f
Show file tree
Hide file tree
Showing 9 changed files with 17 additions and 375 deletions.
Expand Up @@ -49,7 +49,7 @@ case class ResolvedFunctionInvocation(qualifiedName: QualifiedName,
fcnSignature: Option[UserDefinedFunctionSignature],
callArguments: IndexedSeq[Expression])
(val position: InputPosition)
extends Expression with UserDefined {
extends Expression {

def coerceArguments: ResolvedFunctionInvocation = fcnSignature match {
case Some(signature) =>
Expand Down Expand Up @@ -82,12 +82,4 @@ case class ResolvedFunctionInvocation(qualifiedName: QualifiedName,
position))
}
}

override def containsNoUpdates = fcnSignature match {
case None => true
case Some(signature) => signature.accessMode match {
case _: ProcedureReadOnlyAccess => true
case _ => false
}
}
}
Expand Up @@ -37,7 +37,7 @@ case class UserDefinedFunctionSignature(name: QualifiedName,
inputSignature: IndexedSeq[CypherType],
outputType: CypherType,
deprecationInfo: Option[String],
accessMode: ProcedureAccessMode)
accessMode: ProcedureReadOnlyAccess)

object QualifiedName {
def apply(unresolved: UnresolvedCall): QualifiedName =
Expand Down
Expand Up @@ -152,9 +152,8 @@ class TransactionBoundPlanContext(tc: TransactionalContextWrapperv3_1)
.toIndexedSeq
val output = asCypherType(ks.outputType())
val deprecationInfo = asOption(ks.deprecated())
val mode = asCypherProcMode(ks.mode(), ks.allowed())

Some(UserDefinedFunctionSignature(name, input, output, deprecationInfo, mode))
Some(UserDefinedFunctionSignature(name, input, output, deprecationInfo, ProcedureReadOnlyAccess(ks.allowed())))
}
else None
}
Expand Down
Expand Up @@ -292,13 +292,10 @@ case class Unwind(expression: Expression, variable: Variable)(val position: Inpu
}
}

trait UserDefined {
def containsNoUpdates: Boolean
}

abstract class CallClause extends Clause with UserDefined {
abstract class CallClause extends Clause {
override def name = "CALL"
def returnColumns: List[String]
def containsNoUpdates: Boolean
}

case class UnresolvedCall(procedureNamespace: Namespace,
Expand Down
Expand Up @@ -19,7 +19,6 @@
*/
package org.neo4j.cypher.internal.frontend.v3_1.ast

import org.neo4j.cypher.internal.frontend.v3_1.ast.functions.UnresolvedFunction
import org.neo4j.cypher.internal.frontend.v3_1.{InputPosition, SemanticChecking, SemanticError, _}

case class Query(periodicCommitHint: Option[PeriodicCommitHint], part: QueryPart)(val position: InputPosition)
Expand All @@ -43,17 +42,13 @@ sealed trait QueryPart extends ASTNode with ASTPhrase with SemanticCheckable {
case class SingleQuery(clauses: Seq[Clause])(val position: InputPosition) extends QueryPart {
assert(clauses.nonEmpty)

override def containsUpdates = {
override def containsUpdates =
clauses.exists {
case call: UserDefined => !call.containsNoUpdates
case call: CallClause => !call.containsNoUpdates
case _: UpdateClause => true
case other => other.exists {
//If the function is unresolved it might contain updates, we will know for sure after rewrite
case call: FunctionInvocation if call.function == UnresolvedFunction => true
case call: UserDefined => !call.containsNoUpdates
}
case _ => false
}
}

override def returnColumns = clauses.last.returnColumns

override def semanticCheck =
Expand Down
Expand Up @@ -38,23 +38,20 @@ public class FunctionSignature
private final QualifiedName name;
private final List<Neo4jTypes.AnyType> inputSignature;
private final Neo4jTypes.AnyType type;
private final Mode mode;
private final String[] allowed;
private final Optional<String> deprecated;
private final Optional<String> description;

public FunctionSignature( QualifiedName name,
List<Neo4jTypes.AnyType> inputSignature,
Neo4jTypes.AnyType type,
Mode mode,
Optional<String> deprecated,
String[] allowed,
Optional<String> description )
{
this.name = name;
this.inputSignature = unmodifiableList( inputSignature );
this.type = type;
this.mode = mode;
this.deprecated = deprecated;
this.description = description;
this.allowed = allowed;
Expand All @@ -65,11 +62,6 @@ public QualifiedName name()
return name;
}

public Mode mode()
{
return mode;
}

public Optional<String> deprecated()
{
return deprecated;
Expand Down Expand Up @@ -125,7 +117,6 @@ public static class Builder
private final QualifiedName name;
private final List<Neo4jTypes.AnyType> inputSignature = new LinkedList<>();
private Neo4jTypes.AnyType outputType;
private Mode mode = Mode.READ_ONLY;
private String[] allowed = new String[0];
private Optional<String> deprecated = Optional.empty();
private Optional<String> description = Optional.empty();
Expand All @@ -135,12 +126,6 @@ public Builder( String[] namespace, String name )
this.name = new QualifiedName( namespace, name );
}

public Builder mode( Mode mode )
{
this.mode = mode;
return this;
}

public Builder description(String description)
{
this.description = Optional.of( description );
Expand Down Expand Up @@ -179,7 +164,7 @@ public FunctionSignature build()
{
throw new IllegalStateException( "output type must be set" );
}
return new FunctionSignature(name, inputSignature, outputType, mode, deprecated, allowed, description );
return new FunctionSignature(name, inputSignature, outputType, deprecated, allowed, description );
}
}

Expand Down
Expand Up @@ -203,14 +203,12 @@ private ReflectiveFunction compileFunction( Class<?> procDefinition, MethodHandl

Optional<String> description = description( method );
Function function = method.getAnnotation( Function.class );
Mode mode = mode( function.mode() );

Optional<String> deprecated = deprecated( method, function::deprecatedBy,
"Use of @Function(deprecatedBy) without @Deprecated in " + procName );

FunctionSignature signature =
new FunctionSignature( procName, inputSignature, valueConverter.type(),
mode, deprecated, function.allowed(), description );
new FunctionSignature( procName, inputSignature, valueConverter.type(), deprecated, function.allowed(), description );

return new ReflectiveFunction( signature, constructor, procedureMethod, valueConverter, setters );
}
Expand Down
10 changes: 0 additions & 10 deletions community/kernel/src/main/java/org/neo4j/procedure/Function.java
Expand Up @@ -121,15 +121,6 @@
*/
String name() default "";

/**
* 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)
*/
Mode mode() default Mode.DEFAULT;

/**
* When deprecating a function it is useful to indicate a possible
* replacement procedure that clients might show in warnings
Expand All @@ -145,5 +136,4 @@
* @return an array of role names whose users are allowed to execute this function.
*/
String[] allowed() default {};

}

0 comments on commit 905ba2f

Please sign in to comment.