Skip to content

Commit

Permalink
Warn users when using morsel runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Nov 15, 2017
1 parent 47b6fe6 commit fff8ae1
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 17 deletions.
Expand Up @@ -265,6 +265,8 @@ enum Statement implements Status
"This query is not supported by the chosen runtime." ), "This query is not supported by the chosen runtime." ),
FeatureDeprecationWarning( ClientNotification, FeatureDeprecationWarning( ClientNotification,
"This feature is deprecated and will be removed in future versions." ), "This feature is deprecated and will be removed in future versions." ),
ExperimentalFeature( ClientNotification,
"This feature is experimental and should not be used in production systems." ),
JoinHintUnsupportedWarning( ClientNotification, JoinHintUnsupportedWarning( ClientNotification,
"Queries with join hints are not supported by the RULE planner." ), "Queries with join hints are not supported by the RULE planner." ),


Expand Down
Expand Up @@ -21,14 +21,14 @@ package org.neo4j.cypher.internal


import java.time.Clock import java.time.Clock


import org.neo4j.cypher.internal.util.v3_4.InputPosition
import org.neo4j.cypher.internal.compiler.v3_4.CypherCompilerConfiguration import org.neo4j.cypher.internal.compiler.v3_4.CypherCompilerConfiguration
import org.neo4j.cypher.internal.frontend.v3_4.helpers.fixedPoint import org.neo4j.cypher.internal.frontend.v3_4.helpers.fixedPoint
import org.neo4j.cypher.internal.frontend.v3_4.phases.CompilationPhaseTracer import org.neo4j.cypher.internal.frontend.v3_4.phases.CompilationPhaseTracer
import org.neo4j.cypher.internal.util.v3_4.InputPosition
import org.neo4j.cypher.{InvalidArgumentException, SyntaxException, exceptionHandler, _} import org.neo4j.cypher.{InvalidArgumentException, SyntaxException, exceptionHandler, _}
import org.neo4j.graphdb.factory.GraphDatabaseSettings import org.neo4j.graphdb.factory.GraphDatabaseSettings
import org.neo4j.graphdb.impl.notification.NotificationCode.{CREATE_UNIQUE_UNAVAILABLE_FALLBACK, RULE_PLANNER_UNAVAILABLE_FALLBACK, START_DEPRECATED, START_UNAVAILABLE_FALLBACK} import org.neo4j.graphdb.impl.notification.NotificationCode.{CREATE_UNIQUE_UNAVAILABLE_FALLBACK, RULE_PLANNER_UNAVAILABLE_FALLBACK, START_DEPRECATED, START_UNAVAILABLE_FALLBACK}
import org.neo4j.graphdb.impl.notification.NotificationDetail.Factory.startDeprecated import org.neo4j.graphdb.impl.notification.NotificationDetail.Factory.message
import org.neo4j.kernel.GraphDatabaseQueryService import org.neo4j.kernel.GraphDatabaseQueryService
import org.neo4j.kernel.api.KernelAPI import org.neo4j.kernel.api.KernelAPI
import org.neo4j.kernel.configuration.Config import org.neo4j.kernel.configuration.Config
Expand Down Expand Up @@ -202,7 +202,7 @@ class CompilerEngineDelegator(graph: GraphDatabaseQueryService,


private def createStartDeprecatedNotification(ex: util.v3_4.SyntaxException, preParsedQuery: PreParsedQuery) = { private def createStartDeprecatedNotification(ex: util.v3_4.SyntaxException, preParsedQuery: PreParsedQuery) = {
val pos = convertInputPosition(ex.pos.getOrElse(preParsedQuery.offset)) val pos = convertInputPosition(ex.pos.getOrElse(preParsedQuery.offset))
START_DEPRECATED.notification(pos, startDeprecated(ex.getMessage)) START_DEPRECATED.notification(pos, message("START", ex.getMessage))
} }


private def createUniqueNotification(ex: util.v3_4.SyntaxException, preParsedQuery: PreParsedQuery) = { private def createUniqueNotification(ex: util.v3_4.SyntaxException, preParsedQuery: PreParsedQuery) = {
Expand Down
Expand Up @@ -19,8 +19,8 @@
*/ */
package org.neo4j.cypher.internal.compatibility.v3_4.runtime.helpers package org.neo4j.cypher.internal.compatibility.v3_4.runtime.helpers


import org.neo4j.cypher.internal.util.v3_4.InputPosition
import org.neo4j.cypher.internal.frontend.v3_4.notification.{DeprecatedPlannerNotification, InternalNotification, PlannerUnsupportedNotification, RuntimeUnsupportedNotification, _} import org.neo4j.cypher.internal.frontend.v3_4.notification.{DeprecatedPlannerNotification, InternalNotification, PlannerUnsupportedNotification, RuntimeUnsupportedNotification, _}
import org.neo4j.cypher.internal.util.v3_4.InputPosition
import org.neo4j.graphdb import org.neo4j.graphdb
import org.neo4j.graphdb.impl.notification.{NotificationCode, NotificationDetail} import org.neo4j.graphdb.impl.notification.{NotificationCode, NotificationDetail}


Expand All @@ -30,7 +30,7 @@ object InternalWrapping {


def asKernelNotification(offset: Option[InputPosition])(notification: InternalNotification) = notification match { def asKernelNotification(offset: Option[InputPosition])(notification: InternalNotification) = notification match {
case DeprecatedStartNotification(pos, message) => case DeprecatedStartNotification(pos, message) =>
NotificationCode.START_DEPRECATED.notification(pos.withOffset(offset).asInputPosition, NotificationDetail.Factory.startDeprecated(message)) NotificationCode.START_DEPRECATED.notification(pos.withOffset(offset).asInputPosition, NotificationDetail.Factory.message("START", message))
case CartesianProductNotification(pos, variables) => case CartesianProductNotification(pos, variables) =>
NotificationCode.CARTESIAN_PRODUCT.notification(pos.withOffset(offset).asInputPosition, NotificationDetail.Factory.cartesianProduct(variables.asJava)) NotificationCode.CARTESIAN_PRODUCT.notification(pos.withOffset(offset).asInputPosition, NotificationDetail.Factory.cartesianProduct(variables.asJava))
case LengthOnNonPathNotification(pos) => case LengthOnNonPathNotification(pos) =>
Expand Down Expand Up @@ -75,6 +75,8 @@ object InternalWrapping {
NotificationCode.DEPRECATED_PLANNER.notification(graphdb.InputPosition.empty) NotificationCode.DEPRECATED_PLANNER.notification(graphdb.InputPosition.empty)
case ProcedureWarningNotification(pos, name, warning) => case ProcedureWarningNotification(pos, name, warning) =>
NotificationCode.PROCEDURE_WARNING.notification(pos.withOffset(offset).asInputPosition, NotificationDetail.Factory.procedureWarning(name, warning)) NotificationCode.PROCEDURE_WARNING.notification(pos.withOffset(offset).asInputPosition, NotificationDetail.Factory.procedureWarning(name, warning))
case ExperimentalFeatureNotification(msg) =>
NotificationCode.EXPERIMENTAL_FEATURE.notification(graphdb.InputPosition.empty, NotificationDetail.Factory.message("MORSEL", msg))
} }


private implicit class ConvertibleCompilerInputPosition(pos: InputPosition) { private implicit class ConvertibleCompilerInputPosition(pos: InputPosition) {
Expand Down
Expand Up @@ -68,3 +68,5 @@ case class DeprecatedVarLengthBindingNotification(position: InputPosition, varia
case class DeprecatedRelTypeSeparatorNotification(position: InputPosition) extends InternalNotification case class DeprecatedRelTypeSeparatorNotification(position: InputPosition) extends InternalNotification


case object DeprecatedPlannerNotification extends InternalNotification case object DeprecatedPlannerNotification extends InternalNotification

case class ExperimentalFeatureNotification(msg: String) extends InternalNotification
Expand Up @@ -189,8 +189,11 @@ public enum NotificationCode
START_DEPRECATED( START_DEPRECATED(
SeverityLevel.WARNING, SeverityLevel.WARNING,
Status.Statement.FeatureDeprecationWarning, Status.Statement.FeatureDeprecationWarning,
"START has been deprecated and will be removed in a future version." "START has been deprecated and will be removed in a future version."),
); EXPERIMENTAL_FEATURE(
SeverityLevel.WARNING,
Status.Statement.ExperimentalFeature,
"You are using an experimental feature");


private final Status status; private final Status status;
private final String description; private final String description;
Expand Down
Expand Up @@ -102,14 +102,14 @@ public static NotificationDetail indexSeekOrScan( Set<String> labels )
return createNotificationDetail( labels, "indexed label", "indexed labels" ); return createNotificationDetail( labels, "indexed label", "indexed labels" );
} }


public static NotificationDetail startDeprecated( String message ) public static NotificationDetail message( String name, String message )
{ {
return new NotificationDetail() return new NotificationDetail()
{ {
@Override @Override
public String name() public String name()
{ {
return "START"; return name;
} }


@Override @Override
Expand Down
Expand Up @@ -56,5 +56,18 @@ class MorselRuntimeAcceptanceTest extends ExecutionEngineFunSuite {
result.getExecutionPlanDescription.getArguments.get("runtime") should not equal "MORSEL" result.getExecutionPlanDescription.getArguments.get("runtime") should not equal "MORSEL"
} }


test("should warn that morsels are experimental") {
//Given
import scala.collection.JavaConverters._

val result = graph.execute("CYPHER runtime=morsel EXPLAIN MATCH (n) RETURN n")

// When (exhaust result)
val notifications = result.getNotifications.asScala.toSet


//Then
notifications.head.getDescription should equal("You are using an experimental feature (use the morsel runtime at " +
"your own peril, not recommended to be run on production systems)")

}
} }
Expand Up @@ -24,14 +24,15 @@ import org.neo4j.cypher.internal.compatibility.v3_4.runtime._
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.compiled.EnterpriseRuntimeContext import org.neo4j.cypher.internal.compatibility.v3_4.runtime.compiled.EnterpriseRuntimeContext
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.executionplan.StandardInternalExecutionResult.IterateByAccepting import org.neo4j.cypher.internal.compatibility.v3_4.runtime.executionplan.StandardInternalExecutionResult.IterateByAccepting
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.executionplan.{NewRuntimeSuccessRateMonitor, StandardInternalExecutionResult} import org.neo4j.cypher.internal.compatibility.v3_4.runtime.executionplan.{NewRuntimeSuccessRateMonitor, StandardInternalExecutionResult}
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.helpers.InternalWrapping.asKernelNotification
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.phases.CompilationState import org.neo4j.cypher.internal.compatibility.v3_4.runtime.phases.CompilationState
import org.neo4j.cypher.internal.compatibility.v3_4.runtime.slotted.expressions.SlottedExpressionConverters import org.neo4j.cypher.internal.compatibility.v3_4.runtime.slotted.expressions.SlottedExpressionConverters
import org.neo4j.cypher.internal.compiler.v3_4.phases.LogicalPlanState import org.neo4j.cypher.internal.compiler.v3_4.phases.LogicalPlanState
import org.neo4j.cypher.internal.compiler.v3_4.planner.CantCompileQueryException import org.neo4j.cypher.internal.compiler.v3_4.planner.CantCompileQueryException
import org.neo4j.cypher.internal.frontend.v3_4.PlannerName import org.neo4j.cypher.internal.frontend.v3_4.PlannerName
import org.neo4j.cypher.internal.frontend.v3_4.notification.InternalNotification import org.neo4j.cypher.internal.frontend.v3_4.notification.{ExperimentalFeatureNotification, InternalNotification}
import org.neo4j.cypher.internal.frontend.v3_4.phases.CompilationPhaseTracer.CompilationPhase import org.neo4j.cypher.internal.frontend.v3_4.phases.CompilationPhaseTracer.CompilationPhase
import org.neo4j.cypher.internal.frontend.v3_4.phases.{CompilationPhaseTracer, Condition, Phase} import org.neo4j.cypher.internal.frontend.v3_4.phases.{CompilationPhaseTracer, Condition, InternalNotificationLogger, Phase}
import org.neo4j.cypher.internal.planner.v3_4.spi.{GraphStatistics, PlanContext} import org.neo4j.cypher.internal.planner.v3_4.spi.{GraphStatistics, PlanContext}
import org.neo4j.cypher.internal.runtime.interpreted.commands.convert.{CommunityExpressionConverter, ExpressionConverters} import org.neo4j.cypher.internal.runtime.interpreted.commands.convert.{CommunityExpressionConverter, ExpressionConverters}
import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription.Arguments.{Runtime, RuntimeImpl} import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription.Arguments.{Runtime, RuntimeImpl}
Expand Down Expand Up @@ -63,8 +64,11 @@ object BuildVectorizedExecutionPlan extends Phase[EnterpriseRuntimeContext, Logi
else context.dispatcher else context.dispatcher
val fieldNames = from.statement().returnColumns.toArray val fieldNames = from.statement().returnColumns.toArray


context.notificationLogger.log(
ExperimentalFeatureNotification("use the morsel runtime at your own peril, " +
"not recommended to be run on production systems"))
val execPlan = VectorizedExecutionPlan(from.plannerName, operators, pipelines, physicalPlan, fieldNames, val execPlan = VectorizedExecutionPlan(from.plannerName, operators, pipelines, physicalPlan, fieldNames,
dispatcher) dispatcher, context.notificationLogger)
runtimeSuccessRateMonitor.newPlanSeen(from.logicalPlan) runtimeSuccessRateMonitor.newPlanSeen(from.logicalPlan)
new CompilationState(from, Some(execPlan)) new CompilationState(from, Some(execPlan))
} catch { } catch {
Expand All @@ -88,7 +92,8 @@ object BuildVectorizedExecutionPlan extends Phase[EnterpriseRuntimeContext, Logi
pipelineInformation: Map[LogicalPlanId, PipelineInformation], pipelineInformation: Map[LogicalPlanId, PipelineInformation],
physicalPlan: LogicalPlan, physicalPlan: LogicalPlan,
fieldNames: Array[String], fieldNames: Array[String],
dispatcher: Dispatcher) extends executionplan.ExecutionPlan { dispatcher: Dispatcher,
notificationLogger: InternalNotificationLogger) extends executionplan.ExecutionPlan {
override def run(queryContext: QueryContext, planType: ExecutionMode, params: MapValue): InternalExecutionResult = { override def run(queryContext: QueryContext, planType: ExecutionMode, params: MapValue): InternalExecutionResult = {
val taskCloser = new TaskCloser val taskCloser = new TaskCloser
taskCloser.addTask(queryContext.transactionalContext.close) taskCloser.addTask(queryContext.transactionalContext.close)
Expand All @@ -97,9 +102,15 @@ object BuildVectorizedExecutionPlan extends Phase[EnterpriseRuntimeContext, Logi
.addArgument(Runtime(MorselRuntimeName.toTextOutput)) .addArgument(Runtime(MorselRuntimeName.toTextOutput))
.addArgument(RuntimeImpl(MorselRuntimeName.name)) .addArgument(RuntimeImpl(MorselRuntimeName.name))


new VectorizedOperatorExecutionResult(operators, physicalPlan, planDescription, queryContext, if (planType == ExplainMode) {
params, fieldNames, taskCloser, dispatcher) //close all statements
} taskCloser.close(success = true)
ExplainExecutionResult(fieldNames, planDescription(), READ_ONLY,
notificationLogger.notifications.map(asKernelNotification(notificationLogger.offset)))
} else new VectorizedOperatorExecutionResult(operators, physicalPlan, planDescription, queryContext,
params, fieldNames, taskCloser, dispatcher)
}



override def isPeriodicCommit: Boolean = false override def isPeriodicCommit: Boolean = false


Expand Down Expand Up @@ -133,7 +144,7 @@ class VectorizedOperatorExecutionResult(operators: Pipeline,


override def executionMode: ExecutionMode = NormalMode override def executionMode: ExecutionMode = NormalMode


override def notifications: Iterable[Notification] = ??? override def notifications: Iterable[Notification] = Iterable.empty[Notification]


override def withNotifications(notification: Notification*): InternalExecutionResult = this override def withNotifications(notification: Notification*): InternalExecutionResult = this
} }
Expand Down

0 comments on commit fff8ae1

Please sign in to comment.