From d65cf9dc2aa34625de990204f3a7a0f1cea9943d Mon Sep 17 00:00:00 2001 From: Pontus Melke Date: Mon, 11 Jan 2016 12:39:34 +0100 Subject: [PATCH] Removed external dependency on ResultVisitor --- .../compiler/v3_0/codegen/ResultRowImpl.java | 7 +++- .../GeneratedQueryExecution.java | 4 +- .../compiler/v3_0/spi/InternalResultRow.java | 41 +++++++++++++++++++ .../v3_0/spi/InternalResultVisitor.java | 25 +++++++++++ .../v3_0/ExplainExecutionResult.scala | 4 +- .../compiler/v3_0/PipeExecutionResult.scala | 7 ++-- .../AcceptingExecutionResult.scala | 17 ++++---- .../CompiledExecutionResult.scala | 5 +-- .../InternalExecutionResult.scala | 5 +-- .../procs/ProcedureExecutionResult.scala | 5 +-- .../v3_0/helpers/iteratorToVisitable.scala | 10 ++--- .../CompiledExecutionResultTest.scala | 12 +++--- .../helpers/iteratorToVisitableTest.scala | 8 ++-- .../compatibility/CompatibilityFor3_0.scala | 30 ++++++++++++-- .../spi/v3_0/GeneratedQueryStructure.scala | 4 +- .../v3_0/codegen/CodeGeneratorTest.scala | 27 ++++++------ .../v3_0/codegen/ir/CodeGenSugar.scala | 7 ++-- 17 files changed, 151 insertions(+), 67 deletions(-) create mode 100644 community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultRow.java create mode 100644 community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultVisitor.java diff --git a/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/codegen/ResultRowImpl.java b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/codegen/ResultRowImpl.java index 7ac146e6c1f8c..e8d2937af09b4 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/codegen/ResultRowImpl.java +++ b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/codegen/ResultRowImpl.java @@ -23,9 +23,12 @@ import java.util.Map; import java.util.NoSuchElementException; -import org.neo4j.graphdb.*; +import org.neo4j.cypher.internal.compiler.v3_0.spi.InternalResultRow; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Path; +import org.neo4j.graphdb.Relationship; -public class ResultRowImpl implements Result.ResultRow +public class ResultRowImpl implements InternalResultRow { private Map results = new HashMap<>(); diff --git a/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/executionplan/GeneratedQueryExecution.java b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/executionplan/GeneratedQueryExecution.java index 2986e3b825d4d..da5d97e45693b 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/executionplan/GeneratedQueryExecution.java +++ b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/executionplan/GeneratedQueryExecution.java @@ -23,13 +23,13 @@ import org.neo4j.cypher.internal.compiler.v3_0.ExecutionMode; import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription; -import org.neo4j.graphdb.Result; +import org.neo4j.cypher.internal.compiler.v3_0.spi.InternalResultVisitor; public interface GeneratedQueryExecution { List javaColumns(); - void accept( final Result.ResultVisitor visitor ) throws E; + void accept( final InternalResultVisitor visitor ) throws E; ExecutionMode executionMode(); diff --git a/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultRow.java b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultRow.java new file mode 100644 index 0000000000000..367cbdc85ba69 --- /dev/null +++ b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultRow.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.cypher.internal.compiler.v3_0.spi; + +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Path; +import org.neo4j.graphdb.Relationship; + +public interface InternalResultRow +{ + Node getNode( String key ); + + Relationship getRelationship( String key ); + + Object get( String key ); + + String getString( String key ); + + Number getNumber( String key ); + + Boolean getBoolean( String key ); + + Path getPath( String key ); +} diff --git a/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultVisitor.java b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultVisitor.java new file mode 100644 index 0000000000000..e3939bd986dda --- /dev/null +++ b/community/cypher/cypher-compiler-3.0/src/main/java/org/neo4j/cypher/internal/compiler/v3_0/spi/InternalResultVisitor.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.cypher.internal.compiler.v3_0.spi; + +public interface InternalResultVisitor +{ + boolean visit( InternalResultRow row ) throws VisitationException; +} diff --git a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/ExplainExecutionResult.scala b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/ExplainExecutionResult.scala index 8a0de7e4961d7..dcae562f9b747 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/ExplainExecutionResult.scala +++ b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/ExplainExecutionResult.scala @@ -25,10 +25,10 @@ import java.util.Collections import org.neo4j.cypher.internal.compiler.v3_0.executionplan.InternalExecutionResult import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription +import org.neo4j.cypher.internal.compiler.v3_0.spi.InternalResultVisitor import org.neo4j.cypher.internal.frontend.v3_0.notification.InternalNotification import org.neo4j.graphdb.QueryExecutionType.{QueryType, explained} import org.neo4j.graphdb.ResourceIterator -import org.neo4j.graphdb.Result.ResultVisitor case class ExplainExecutionResult(columns: List[String], executionPlanDescription: InternalPlanDescription, queryType: QueryType, @@ -63,7 +63,7 @@ case class ExplainExecutionResult(columns: List[String], def hasNext = false - override def accept[EX <: Exception](visitor: ResultVisitor[EX]) = {} + override def accept[EX <: Exception](visitor: InternalResultVisitor[EX]) = {} } final class EmptyResourceIterator[T]() extends ResourceIterator[T] { diff --git a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/PipeExecutionResult.scala b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/PipeExecutionResult.scala index 544c464eb985f..11a68a693106a 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/PipeExecutionResult.scala +++ b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/PipeExecutionResult.scala @@ -22,17 +22,16 @@ package org.neo4j.cypher.internal.compiler.v3_0 import java.io.PrintWriter import java.util -import org.neo4j.cypher.internal.frontend.v3_0.helpers.JavaCompatibility._ import org.neo4j.cypher.internal.compiler.v3_0.executionplan.InternalExecutionResult import org.neo4j.cypher.internal.compiler.v3_0.helpers.{CollectionSupport, iteratorToVisitable} import org.neo4j.cypher.internal.compiler.v3_0.pipes.QueryState import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription -import org.neo4j.cypher.internal.compiler.v3_0.spi.QueryContext +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultVisitor, QueryContext} import org.neo4j.cypher.internal.frontend.v3_0.helpers.Eagerly +import org.neo4j.cypher.internal.frontend.v3_0.helpers.JavaCompatibility._ import org.neo4j.cypher.internal.frontend.v3_0.notification.InternalNotification import org.neo4j.graphdb.QueryExecutionType.{QueryType, profiled, query} import org.neo4j.graphdb.{NotFoundException, ResourceIterator} -import org.neo4j.graphdb.Result.ResultVisitor import scala.collection.JavaConverters._ import scala.collection.Map @@ -104,7 +103,7 @@ class PipeExecutionResult(val result: ResultIterator, //notifications only present for EXPLAIN override val notifications = Iterable.empty[InternalNotification] - def accept[EX <: Exception](visitor: ResultVisitor[EX]) = { + def accept[EX <: Exception](visitor: InternalResultVisitor[EX]) = { try { iteratorToVisitable.accept(self, visitor) } finally { diff --git a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/AcceptingExecutionResult.scala b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/AcceptingExecutionResult.scala index 8032416dacfd7..69e0c12827ba8 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/AcceptingExecutionResult.scala +++ b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/AcceptingExecutionResult.scala @@ -26,13 +26,12 @@ import org.neo4j.cypher.internal.compiler.v3_0.commands.values.KeyToken import org.neo4j.cypher.internal.compiler.v3_0.helpers.IsCollection import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription.Arguments.{Planner, Runtime} -import org.neo4j.cypher.internal.compiler.v3_0.spi.QueryContext +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultRow, InternalResultVisitor, QueryContext} import org.neo4j.cypher.internal.compiler.v3_0.{TaskCloser, _} import org.neo4j.cypher.internal.frontend.v3_0.EntityNotFoundException import org.neo4j.cypher.internal.frontend.v3_0.helpers.Eagerly import org.neo4j.cypher.internal.frontend.v3_0.notification.InternalNotification import org.neo4j.graphdb.QueryExecutionType._ -import org.neo4j.graphdb.Result.{ResultRow, ResultVisitor} import org.neo4j.graphdb.{ResourceIterator, _} import scala.collection.{Map, mutable} @@ -101,7 +100,7 @@ abstract class AcceptingExecutionResult(taskCloser: TaskCloser, override def javaColumns: util.List[String] = self.javaColumns - override def accept[EX <: Exception](visitor: ResultVisitor[EX]): Unit = throw new UnsupportedOperationException + override def accept[EX <: Exception](visitor: InternalResultVisitor[EX]): Unit = throw new UnsupportedOperationException override def executionPlanDescription(): InternalPlanDescription = self.executionPlanDescription() .addArgument(Planner(planner.name)).addArgument(Runtime(runtime.name)) @@ -157,14 +156,14 @@ abstract class AcceptingExecutionResult(taskCloser: TaskCloser, //TODO when allowing writes this should be moved to the generated class protected def queryType: QueryType = QueryType.READ_ONLY - private def populateResults(results: util.List[util.Map[String, Any]])(row: ResultRow) = { + private def populateResults(results: util.List[util.Map[String, Any]])(row: InternalResultRow) = { val map = new util.HashMap[String, Any]() columns.foreach(c => map.put(c, row.get(c))) results.add(map) } private def populateDumpToStringResults(builder: mutable.Builder[Map[String, String], Seq[Map[String, String]]]) - (row: ResultRow) = { + (row: InternalResultRow) = { val map = new mutable.HashMap[String, String]() columns.foreach(c => map.put(c, text(row.get(c)))) @@ -204,10 +203,10 @@ abstract class AcceptingExecutionResult(taskCloser: TaskCloser, case (k, v) => k + " -> " + text(v) }.mkString("{", ", ", "}") - private def doInAccept[T](body: ResultRow => T) = { + private def doInAccept[T](body: InternalResultRow => T) = { if (!taskCloser.isClosed) { - accept(new ResultVisitor[RuntimeException] { - override def visit(row: ResultRow): Boolean = { + accept(new InternalResultVisitor[RuntimeException] { + override def visit(row: InternalResultRow): Boolean = { body(row) true } @@ -270,7 +269,7 @@ abstract class AcceptingExecutionResult(taskCloser: TaskCloser, def javaColumns: util.List[String] //todo this should not depend on external visitor - def accept[EX <: Exception](visitor: ResultVisitor[EX]): Unit + def accept[EX <: Exception](visitor: InternalResultVisitor[EX]): Unit override def executionPlanDescription(): InternalPlanDescription } diff --git a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResult.scala b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResult.scala index cf815f4e34d11..95c2714914a4a 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResult.scala +++ b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResult.scala @@ -23,9 +23,8 @@ import java.util import org.neo4j.cypher.internal.compiler.v3_0._ import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription -import org.neo4j.cypher.internal.compiler.v3_0.spi.QueryContext +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultVisitor, QueryContext} import org.neo4j.cypher.internal.frontend.v3_0.ProfilerStatisticsNotReadyException -import org.neo4j.graphdb.Result.ResultVisitor trait SuccessfulCloseable { def success(): Unit @@ -48,7 +47,7 @@ class CompiledExecutionResult(taskCloser: TaskCloser, override def javaColumns: util.List[String] = compiledCode.javaColumns() - override def accept[EX <: Exception](visitor: ResultVisitor[EX]): Unit = + override def accept[EX <: Exception](visitor: InternalResultVisitor[EX]): Unit = compiledCode.accept(visitor) override def executionPlanDescription(): InternalPlanDescription = { diff --git a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/InternalExecutionResult.scala b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/InternalExecutionResult.scala index 9d41d42838955..31cda6518f710 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/InternalExecutionResult.scala +++ b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/InternalExecutionResult.scala @@ -23,8 +23,8 @@ import java.io.PrintWriter import org.neo4j.cypher.internal.compiler.v3_0.InternalQueryStatistics import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription +import org.neo4j.cypher.internal.compiler.v3_0.spi.InternalResultVisitor import org.neo4j.cypher.internal.frontend.v3_0.notification.InternalNotification -import org.neo4j.graphdb.Result.ResultVisitor import org.neo4j.graphdb.{QueryExecutionType, ResourceIterator} trait InternalExecutionResult extends Iterator[Map[String, Any]] { @@ -41,7 +41,6 @@ trait InternalExecutionResult extends Iterator[Map[String, Any]] { def planDescriptionRequested: Boolean def executionType: QueryExecutionType def notifications: Iterable[InternalNotification] - //todo this should not depend on external visitor @throws(classOf[Exception]) - def accept[EX <: Exception](visitor: ResultVisitor[EX]) + def accept[EX <: Exception](visitor: InternalResultVisitor[EX]) } diff --git a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/procs/ProcedureExecutionResult.scala b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/procs/ProcedureExecutionResult.scala index 0a4c6d1c5f8ee..aefdbdbe13fb7 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/procs/ProcedureExecutionResult.scala +++ b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/procs/ProcedureExecutionResult.scala @@ -22,9 +22,8 @@ package org.neo4j.cypher.internal.compiler.v3_0.executionplan.procs import org.neo4j.cypher.internal.compiler.v3_0.codegen.ResultRowImpl import org.neo4j.cypher.internal.compiler.v3_0.executionplan.AcceptingExecutionResult import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription -import org.neo4j.cypher.internal.compiler.v3_0.spi.{ProcedureSignature, QueryContext} +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultVisitor, ProcedureSignature, QueryContext} import org.neo4j.cypher.internal.compiler.v3_0.{ExecutionMode, InternalQueryStatistics, NormalMode, TaskCloser} -import org.neo4j.graphdb.Result.ResultVisitor import scala.collection.JavaConverters._ @@ -48,7 +47,7 @@ case class ProcedureExecutionResult[E <: Exception](taskCloser: TaskCloser, override def javaColumns: java.util.List[String] = signature.outputSignature.seq.map(_.name).asJava - override def accept[EX <: Exception](visitor: ResultVisitor[EX]) = { + override def accept[EX <: Exception](visitor: InternalResultVisitor[EX]) = { context.callReadOnlyProcedure(signature, args).foreach { res => var i = 0 val row = new ResultRowImpl diff --git a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitable.scala b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitable.scala index e4496362b3642..b998676352bed 100644 --- a/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitable.scala +++ b/community/cypher/cypher-compiler-3.0/src/main/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitable.scala @@ -19,16 +19,16 @@ */ package org.neo4j.cypher.internal.compiler.v3_0.helpers +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultRow, InternalResultVisitor} import org.neo4j.cypher.internal.frontend.v3_0.helpers.Eagerly -import org.neo4j.graphdb.{Path, Relationship, Node} -import org.neo4j.graphdb.Result.{ResultRow, ResultVisitor} +import org.neo4j.graphdb.{Node, Path, Relationship} -import scala.collection.Map import scala.collection.JavaConverters._ +import scala.collection.Map object iteratorToVisitable { - def accept[EX <: Exception](iterator: Iterator[Map[String, Any]], visitor: ResultVisitor[EX]) = { + def accept[EX <: Exception](iterator: Iterator[Map[String, Any]], visitor: InternalResultVisitor[EX]) = { val row = new MapResultRow() var continue = true while (continue && iterator.hasNext) { @@ -37,7 +37,7 @@ object iteratorToVisitable { } } - private class MapResultRow extends ResultRow { + private class MapResultRow extends InternalResultRow { var map: Map[String, Any] = Map.empty diff --git a/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResultTest.scala b/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResultTest.scala index b41105eedd826..303fa3e3c862f 100644 --- a/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResultTest.scala +++ b/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/executionplan/CompiledExecutionResultTest.scala @@ -23,9 +23,9 @@ import java.util import org.neo4j.cypher.internal.compiler.v3_0.codegen.ResultRowImpl import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultRow, InternalResultVisitor} import org.neo4j.cypher.internal.compiler.v3_0.{ExecutionMode, NormalMode, TaskCloser} import org.neo4j.cypher.internal.frontend.v3_0.test_helpers.CypherFunSuite -import org.neo4j.graphdb.Result.{ResultRow, ResultVisitor} import org.neo4j.helpers.collection.Iterables._ import scala.collection.JavaConverters._ @@ -120,8 +120,8 @@ class CompiledExecutionResultTest extends CypherFunSuite { }) // when - result.accept(new ResultVisitor[Exception] { - override def visit(row: ResultRow): Boolean = { + result.accept(new InternalResultVisitor[Exception] { + override def visit(row: InternalResultRow): Boolean = { false } }) @@ -135,8 +135,8 @@ class CompiledExecutionResultTest extends CypherFunSuite { val result = newCompiledExecutionResult(javaMap("a" -> "1", "b" -> "2")) // when - result.accept(new ResultVisitor[Exception] { - override def visit(row: ResultRow): Boolean = { + result.accept(new InternalResultVisitor[Exception] { + override def visit(row: InternalResultRow): Boolean = { true } }) @@ -154,7 +154,7 @@ class CompiledExecutionResultTest extends CypherFunSuite { override def setSuccessfulCloseable(closeable: SuccessfulCloseable){} override def javaColumns(): util.List[String] = new util.ArrayList(row.keySet()) override def executionMode(): ExecutionMode = NormalMode - override def accept[E <: Exception](visitor: ResultVisitor[E]): Unit = { + override def accept[E <: Exception](visitor: InternalResultVisitor[E]): Unit = { try { val rowImpl = new ResultRowImpl() row.asScala.foreach { case (k, v) => rowImpl.set(k, v) } diff --git a/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitableTest.scala b/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitableTest.scala index f8b77f3743f24..e2bc286febb4c 100644 --- a/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitableTest.scala +++ b/community/cypher/cypher-compiler-3.0/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/helpers/iteratorToVisitableTest.scala @@ -20,8 +20,8 @@ package org.neo4j.cypher.internal.compiler.v3_0.helpers import org.mockito.Mockito.verifyZeroInteractions +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultRow, InternalResultVisitor} import org.neo4j.cypher.internal.frontend.v3_0.test_helpers.CypherFunSuite -import org.neo4j.graphdb.Result.{ResultRow, ResultVisitor} import scala.collection.mutable.ArrayBuffer @@ -54,7 +54,7 @@ class iteratorToVisitableTest extends CypherFunSuite { test("should accept nothing if iterator is empty") { // Given - val visitor = mock[ResultVisitor[RuntimeException]] + val visitor = mock[InternalResultVisitor[RuntimeException]] // When iteratorToVisitable.accept(Iterator.empty, visitor) @@ -63,13 +63,13 @@ class iteratorToVisitableTest extends CypherFunSuite { verifyZeroInteractions(visitor) } - private case class RecordingResultVisitor(columns: String*)(rowsToAccept: Int = Int.MaxValue) extends ResultVisitor[RuntimeException] { + private case class RecordingResultVisitor(columns: String*)(rowsToAccept: Int = Int.MaxValue) extends InternalResultVisitor[RuntimeException] { require(rowsToAccept >= 0) val recorded = new ArrayBuffer[(String, Any)]() - def visit(row: ResultRow) = { + def visit(row: InternalResultRow) = { recorded ++= columns.map(name => name -> row.get(name)) recorded.size != rowsToAccept } diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/CompatibilityFor3_0.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/CompatibilityFor3_0.scala index 400dff7b2c487..fff27ec5de2c9 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/CompatibilityFor3_0.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/compatibility/CompatibilityFor3_0.scala @@ -20,7 +20,7 @@ package org.neo4j.cypher.internal.compatibility import java.io.PrintWriter -import java.util +import java.{lang, util} import org.neo4j.cypher._ import org.neo4j.cypher.internal._ @@ -28,6 +28,7 @@ import org.neo4j.cypher.internal.compiler.v3_0 import org.neo4j.cypher.internal.compiler.v3_0.executionplan.{ExecutionPlan => ExecutionPlan_v3_0, InternalExecutionResult} import org.neo4j.cypher.internal.compiler.v3_0.planDescription.InternalPlanDescription.Arguments._ import org.neo4j.cypher.internal.compiler.v3_0.planDescription.{Argument, InternalPlanDescription, PlanDescriptionArgumentSerializer} +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultRow, InternalResultVisitor} import org.neo4j.cypher.internal.compiler.v3_0.tracing.rewriters.RewriterStepSequencer import org.neo4j.cypher.internal.compiler.v3_0.{CypherCompilerFactory, DPPlannerName, ExplainMode => ExplainModev3_0, IDPPlannerName, InfoLogger, Monitors, NormalMode => NormalModev3_0, PlannerName, ProfileMode => ProfileModev3_0, _} import org.neo4j.cypher.internal.frontend.v3_0.notification.{InternalNotification, PlannerUnsupportedNotification, RuntimeUnsupportedNotification, _} @@ -36,9 +37,9 @@ import org.neo4j.cypher.internal.frontend.v3_0.{CypherException => InternalCyphe import org.neo4j.cypher.internal.spi.v3_0.TransactionBoundQueryContext.IndexSearchMonitor import org.neo4j.cypher.internal.spi.v3_0.{GeneratedQueryStructure, TransactionBoundGraphStatistics, TransactionBoundPlanContext, TransactionBoundQueryContext} import org.neo4j.cypher.javacompat.ProfilerStatistics -import org.neo4j.graphdb.Result.ResultVisitor +import org.neo4j.graphdb.Result.{ResultRow, ResultVisitor} import org.neo4j.graphdb.impl.notification.{NotificationCode, NotificationDetail} -import org.neo4j.graphdb.{GraphDatabaseService, InputPosition, QueryExecutionType, ResourceIterator} +import org.neo4j.graphdb.{GraphDatabaseService, InputPosition, Node, Path, QueryExecutionType, Relationship, ResourceIterator} import org.neo4j.helpers.Clock import org.neo4j.kernel.GraphDatabaseAPI import org.neo4j.kernel.api.{KernelAPI, Statement} @@ -337,10 +338,31 @@ case class ExecutionResultWrapperFor3_0(inner: InternalExecutionResult, planner: } override def accept[EX <: Exception](visitor: ResultVisitor[EX]) = exceptionHandlerFor3_0.runSafely { - inner.accept(visitor) + inner.accept(wrapVisitor(visitor)) endQueryExecution() } + private def wrapVisitor[EX <: Exception](visitor: ResultVisitor[EX]) = new InternalResultVisitor[EX] { + override def visit(row: InternalResultRow) = visitor.visit(unwrapResultRow(row)) + } + + private def unwrapResultRow(row: InternalResultRow): ResultRow = new ResultRow { + + override def getRelationship(key: String): Relationship = row.getRelationship(key) + + override def get(key: String): AnyRef = row.get(key) + + override def getBoolean(key: String): lang.Boolean = row.getBoolean(key) + + override def getPath(key: String): Path = row.getPath(key) + + override def getNode(key: String): Node = row.getNode(key) + + override def getNumber(key: String): Number = row.getNumber(key) + + override def getString(key: String): String = row.getString(key) + } + override def toString() = { getClass.getName + "@" + Integer.toHexString(hashCode()) } diff --git a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala index 8180e69b82701..dc185c635bbd4 100644 --- a/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala +++ b/community/cypher/cypher/src/main/scala/org/neo4j/cypher/internal/spi/v3_0/GeneratedQueryStructure.scala @@ -38,7 +38,7 @@ import org.neo4j.cypher.internal.compiler.v3_0.executionplan._ import org.neo4j.cypher.internal.compiler.v3_0.helpers._ import org.neo4j.cypher.internal.compiler.v3_0.planDescription.{Id, InternalPlanDescription} import org.neo4j.cypher.internal.compiler.v3_0.planner.CantCompileQueryException -import org.neo4j.cypher.internal.compiler.v3_0.spi.QueryContext +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultVisitor, QueryContext} import org.neo4j.cypher.internal.compiler.v3_0.{ExecutionMode, TaskCloser} import org.neo4j.cypher.internal.frontend.v3_0.symbols.CypherType import org.neo4j.cypher.internal.frontend.v3_0.{CypherExecutionException, ParameterNotFoundException, SemanticDirection, symbols} @@ -96,7 +96,7 @@ object GeneratedQueryStructure extends CodeStructure[GeneratedQuery] { clazz.generate(Templates.JAVA_COLUMNS) using(clazz.generate(MethodDeclaration.method(typeRef[Unit], "accept", - Parameter.param(parameterizedType(classOf[ResultVisitor[_]], typeParameter("E")), "visitor")). + Parameter.param(parameterizedType(classOf[InternalResultVisitor[_]], typeParameter("E")), "visitor")). parameterizedWith("E", extending(typeRef[Exception])). throwsException(typeParameter("E")))) { method => using(method.tryBlock()) { body => diff --git a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/CodeGeneratorTest.scala b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/CodeGeneratorTest.scala index 1e7418971f3ec..c8140b95b0357 100644 --- a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/CodeGeneratorTest.scala +++ b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/CodeGeneratorTest.scala @@ -28,13 +28,12 @@ import org.neo4j.cypher.internal.compiler.v3_0.executionplan.ExecutionPlanBuilde import org.neo4j.cypher.internal.compiler.v3_0.executionplan.InternalExecutionResult import org.neo4j.cypher.internal.compiler.v3_0.planner.LogicalPlanningTestSupport import org.neo4j.cypher.internal.compiler.v3_0.planner.logical.plans._ -import org.neo4j.cypher.internal.compiler.v3_0.spi.QueryContext +import org.neo4j.cypher.internal.compiler.v3_0.spi.{InternalResultRow, InternalResultVisitor, QueryContext} import org.neo4j.cypher.internal.compiler.v3_0.{CostBasedPlannerName, NormalMode, TaskCloser} import org.neo4j.cypher.internal.frontend.v3_0.ast._ import org.neo4j.cypher.internal.frontend.v3_0.test_helpers.CypherFunSuite import org.neo4j.cypher.internal.frontend.v3_0.{ParameterNotFoundException, SemanticDirection, SemanticTable} import org.neo4j.cypher.internal.spi.v3_0.GeneratedQueryStructure -import org.neo4j.graphdb.Result.{ResultRow, ResultVisitor} import org.neo4j.graphdb.{Direction, Node, Relationship} import org.neo4j.helpers.Clock import org.neo4j.kernel.api.ReadOperations @@ -748,8 +747,8 @@ class CodeGeneratorTest extends CypherFunSuite with LogicalPlanningTestSupport { // then verifyZeroInteractions(closer) - val visitor = mock[ResultVisitor[RuntimeException]] - when(visitor.visit(any[ResultRow])).thenReturn(true) + val visitor = mock[InternalResultVisitor[RuntimeException]] + when(visitor.visit(any[InternalResultRow])).thenReturn(true) compiled.accept(visitor) verify(closer).close(success = true) } @@ -764,8 +763,8 @@ class CodeGeneratorTest extends CypherFunSuite with LogicalPlanningTestSupport { // then verifyZeroInteractions(closer) - val visitor = mock[ResultVisitor[RuntimeException]] - when(visitor.visit(any[ResultRow])).thenReturn(false) + val visitor = mock[InternalResultVisitor[RuntimeException]] + when(visitor.visit(any[InternalResultRow])).thenReturn(false) compiled.accept(visitor) verify(closer).close(success = true) } @@ -780,9 +779,9 @@ class CodeGeneratorTest extends CypherFunSuite with LogicalPlanningTestSupport { // then verifyZeroInteractions(closer) - val visitor = mock[ResultVisitor[RuntimeException]] + val visitor = mock[InternalResultVisitor[RuntimeException]] val exception = new scala.RuntimeException() - when(visitor.visit(any[ResultRow])).thenThrow(exception) + when(visitor.visit(any[InternalResultRow])).thenThrow(exception) intercept[RuntimeException] { compiled.accept(visitor) @@ -799,9 +798,9 @@ class CodeGeneratorTest extends CypherFunSuite with LogicalPlanningTestSupport { val compiled = compileAndExecute( plan, taskCloser = closer ) // then - val visitor = mock[ResultVisitor[RuntimeException]] + val visitor = mock[InternalResultVisitor[RuntimeException]] val exception = new scala.RuntimeException() - when(visitor.visit(any[ResultRow])).thenThrow(exception) + when(visitor.visit(any[InternalResultRow])).thenThrow(exception) try { compiled.accept(visitor) fail("should have thrown error") @@ -1047,8 +1046,8 @@ class CodeGeneratorTest extends CypherFunSuite with LogicalPlanningTestSupport { private def getNodesFromResult(plan: InternalExecutionResult, columns: String*) = { val res = Seq.newBuilder[Map[String, Node]] - plan.accept(new ResultVisitor[RuntimeException]() { - override def visit(element: ResultRow): Boolean = { + plan.accept(new InternalResultVisitor[RuntimeException]() { + override def visit(element: InternalResultRow): Boolean = { res += columns.map(col => col -> element.getNode(col)).toMap true } @@ -1059,8 +1058,8 @@ class CodeGeneratorTest extends CypherFunSuite with LogicalPlanningTestSupport { private def getResult(plan: InternalExecutionResult, columns: String*) = { val res = Seq.newBuilder[Map[String, Any]] - plan.accept(new ResultVisitor[RuntimeException]() { - override def visit(element: ResultRow): Boolean = { + plan.accept(new InternalResultVisitor[RuntimeException]() { + override def visit(element: InternalResultRow): Boolean = { res += columns.map(col => col -> element.get(col)).toMap true } diff --git a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/ir/CodeGenSugar.scala b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/ir/CodeGenSugar.scala index 24184c6d8ed44..ca8dcfb9c5274 100644 --- a/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/ir/CodeGenSugar.scala +++ b/community/cypher/cypher/src/test/scala/org/neo4j/cypher/internal/compiler/v3_0/codegen/ir/CodeGenSugar.scala @@ -27,13 +27,12 @@ import org.neo4j.cypher.internal.compiler.v3_0.executionplan.ExecutionPlanBuilde import org.neo4j.cypher.internal.compiler.v3_0.executionplan._ import org.neo4j.cypher.internal.compiler.v3_0.planDescription.{Id, InternalPlanDescription} import org.neo4j.cypher.internal.compiler.v3_0.planner.logical.plans.LogicalPlan -import org.neo4j.cypher.internal.compiler.v3_0.spi.{GraphStatistics, PlanContext, QueryContext} +import org.neo4j.cypher.internal.compiler.v3_0.spi.{GraphStatistics, InternalResultRow, InternalResultVisitor, PlanContext, QueryContext} import org.neo4j.cypher.internal.compiler.v3_0.{CostBasedPlannerName, ExecutionMode, NormalMode, TaskCloser} import org.neo4j.cypher.internal.frontend.v3_0.SemanticTable import org.neo4j.cypher.internal.spi.v3_0.TransactionBoundQueryContext.IndexSearchMonitor import org.neo4j.cypher.internal.spi.v3_0.{GeneratedQueryStructure, TransactionBoundQueryContext} import org.neo4j.graphdb.GraphDatabaseService -import org.neo4j.graphdb.Result.{ResultRow, ResultVisitor} import org.neo4j.helpers.Clock import org.neo4j.kernel.GraphDatabaseAPI import org.neo4j.kernel.api.Statement @@ -92,8 +91,8 @@ trait CodeGenSugar extends MockitoSugar { def evaluate(result: InternalExecutionResult): List[Map[String, Object]] = { var rows = List.empty[Map[String, Object]] val columns: List[String] = result.columns - result.accept(new ResultVisitor[RuntimeException] { - override def visit(row: ResultRow): Boolean = { + result.accept(new InternalResultVisitor[RuntimeException] { + override def visit(row: InternalResultRow): Boolean = { rows = rows :+ columns.map(key => (key, row.get(key))).toMap true }