Skip to content

Commit

Permalink
Remove LogicalPlanId and use the new Id instead.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lojjs committed Dec 22, 2017
1 parent 12f9220 commit 3160a5a
Show file tree
Hide file tree
Showing 149 changed files with 696 additions and 843 deletions.
Expand Up @@ -20,7 +20,7 @@
package org.neo4j.cypher.internal.v3_4.logical.plans package org.neo4j.cypher.internal.v3_4.logical.plans


import org.neo4j.cypher.internal.ir.v3_4.{CardinalityEstimation, IdName, PlannerQuery} import org.neo4j.cypher.internal.ir.v3_4.{CardinalityEstimation, IdName, PlannerQuery}
import org.neo4j.cypher.internal.util.v3_4.attribution.IdGen import org.neo4j.cypher.internal.util.v3_4.attribution.{IdGen, SameId}
import org.neo4j.cypher.internal.util.v3_4.symbols._ import org.neo4j.cypher.internal.util.v3_4.symbols._


/** /**
Expand All @@ -32,20 +32,20 @@ case class Argument(argumentIds: Set[IdName] = Set.empty)(val solved: PlannerQue
def availableSymbols: Set[IdName] = argumentIds def availableSymbols: Set[IdName] = argumentIds


override def updateSolved(newSolved: PlannerQuery with CardinalityEstimation): Argument = { override def updateSolved(newSolved: PlannerQuery with CardinalityEstimation): Argument = {
val resultingPlan = copy(argumentIds)(newSolved) val resultingPlan = copy(argumentIds)(newSolved)(SameId(this.id))
resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer) resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer)
resultingPlan resultingPlan
} }


override def copyPlan(): LogicalPlan = { override def copyPlan(): LogicalPlan = {
val resultingPlan = this.copy(argumentIds)(solved).asInstanceOf[this.type] val resultingPlan = this.copy(argumentIds)(solved)(SameId(this.id)).asInstanceOf[this.type]
resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer) resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer)
resultingPlan resultingPlan
} }


override def dup(children: Seq[AnyRef]) = children.size match { override def dup(children: Seq[AnyRef]) = children.size match {
case 1 => case 1 =>
val resultingPlan = copy(children.head.asInstanceOf[Set[IdName]])(solved).asInstanceOf[this.type] val resultingPlan = copy(children.head.asInstanceOf[Set[IdName]])(solved)(SameId(this.id)).asInstanceOf[this.type]
resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer) resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer)
resultingPlan resultingPlan
} }
Expand Down
Expand Up @@ -22,10 +22,10 @@ package org.neo4j.cypher.internal.v3_4.logical.plans
import java.lang.reflect.Method import java.lang.reflect.Method


import org.neo4j.cypher.internal.util.v3_4.Foldable._ import org.neo4j.cypher.internal.util.v3_4.Foldable._
import org.neo4j.cypher.internal.util.v3_4.{Foldable, InternalException, Unchangeable} import org.neo4j.cypher.internal.util.v3_4.{Foldable, InternalException, Rewritable, Unchangeable}
import org.neo4j.cypher.internal.util.v3_4.Rewritable._ import org.neo4j.cypher.internal.util.v3_4.Rewritable._
import org.neo4j.cypher.internal.ir.v3_4.{CardinalityEstimation, IdName, PlannerQuery, Strictness} import org.neo4j.cypher.internal.ir.v3_4.{CardinalityEstimation, IdName, PlannerQuery, Strictness}
import org.neo4j.cypher.internal.util.v3_4.attribution.IdGen import org.neo4j.cypher.internal.util.v3_4.attribution.{IdGen, SameId}
import org.neo4j.cypher.internal.v3_4.expressions.Expression import org.neo4j.cypher.internal.v3_4.expressions.Expression


object LogicalPlan { object LogicalPlan {
Expand All @@ -42,7 +42,7 @@ abstract class LogicalPlan(idGen: IdGen)
extends Product extends Product
with Foldable with Foldable
with Strictness with Strictness
with RewritableWithMemory { with Rewritable {


self => self =>


Expand All @@ -56,44 +56,14 @@ abstract class LogicalPlan(idGen: IdGen)
val readTransactionLayer: Unchangeable[Int] = new Unchangeable[Int] val readTransactionLayer: Unchangeable[Int] = new Unchangeable[Int]


val id = idGen.id() val id = idGen.id()
// --------
/*
A id for the logical plan operator, unique inside of the given query tree. These identifiers will be
copied to a rewritten version of the logical plan, as long as there is a one-to-one mapping between
rewritten plans. In other words - once ids have been assigned, plan rewriting should not collapse multiple
operators into one, or split a single one into multiple new ones.
*/
def assignedId: LogicalPlanId = _id.getOrElse(throw new InternalException("Plan has not had an id assigned yet"))

def assignIds(): Unit = {
if (_id.nonEmpty)
throw new InternalException("Id has already been assigned")

var count = 0
val plans = this.findByAllClass[LogicalPlan]
plans.foreach { lp =>
lp._id = Some(new LogicalPlanId(count))
count = count + 1
}
assignedId
}

private var _id: Option[LogicalPlanId] = None

override def rememberMe(old: AnyRef): Unit = _id = old.asInstanceOf[LogicalPlan]._id

// This should only be used for converting old versions of LogicalPlans
def setIdTo(id: LogicalPlanId) : Unit = _id = Some(id)
// ^ TODO DIE
// ---------


def leaves: Seq[LogicalPlan] = this.treeFold(Seq.empty[LogicalPlan]) { def leaves: Seq[LogicalPlan] = this.treeFold(Seq.empty[LogicalPlan]) {
case plan: LogicalPlan case plan: LogicalPlan
if plan.lhs.isEmpty && plan.rhs.isEmpty => acc => (acc :+ plan, Some(identity)) if plan.lhs.isEmpty && plan.rhs.isEmpty => acc => (acc :+ plan, Some(identity))
} }


def updateSolved(newSolved: PlannerQuery with CardinalityEstimation): LogicalPlan = { def updateSolved(newSolved: PlannerQuery with CardinalityEstimation): LogicalPlan = {
val arguments = this.children.toList :+ newSolved :+ idGen val arguments = this.children.toList :+ newSolved :+ SameId(this.id)
try { try {
val resultingPlan = copyConstructor.invoke(this, arguments: _*).asInstanceOf[this.type] val resultingPlan = copyConstructor.invoke(this, arguments: _*).asInstanceOf[this.type]
resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer) resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer)
Expand All @@ -106,7 +76,7 @@ abstract class LogicalPlan(idGen: IdGen)


def copyPlan(): LogicalPlan = { def copyPlan(): LogicalPlan = {
try { try {
val arguments = this.children.toList :+ solved :+ idGen val arguments = this.children.toList :+ solved :+ SameId(this.id)
val resultingPlan = copyConstructor.invoke(this, arguments: _*).asInstanceOf[this.type] val resultingPlan = copyConstructor.invoke(this, arguments: _*).asInstanceOf[this.type]
resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer) resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer)
resultingPlan resultingPlan
Expand All @@ -131,11 +101,11 @@ abstract class LogicalPlan(idGen: IdGen)
val resultingPlan = val resultingPlan =
if (params.length == args.length + 1 if (params.length == args.length + 1
&& params.last.isAssignableFrom(classOf[IdGen])) && params.last.isAssignableFrom(classOf[IdGen]))
constructor.invoke(this, args :+ this.idGen: _*).asInstanceOf[this.type] constructor.invoke(this, args :+ SameId(this.id): _*).asInstanceOf[this.type]
else if ((params.length == args.length + 2) else if ((params.length == args.length + 2)
&& params(params.length - 2).isAssignableFrom(classOf[PlannerQuery]) && params(params.length - 2).isAssignableFrom(classOf[PlannerQuery])
&& params(params.length - 1).isAssignableFrom(classOf[IdGen])) && params(params.length - 1).isAssignableFrom(classOf[IdGen]))
constructor.invoke(this, args :+ this.solved :+ this.idGen: _*).asInstanceOf[this.type] constructor.invoke(this, args :+ this.solved :+ SameId(this.id): _*).asInstanceOf[this.type]
else else
constructor.invoke(this, args: _*).asInstanceOf[this.type] constructor.invoke(this, args: _*).asInstanceOf[this.type]
resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer) resultingPlan.readTransactionLayer.copyFrom(readTransactionLayer)
Expand Down Expand Up @@ -230,19 +200,3 @@ final case class SchemaIndexSeekUsage(identifier: String, labelId : Int, label:
final case class SchemaIndexScanUsage(identifier: String, labelId : Int, label: String, propertyKey: String) extends IndexUsage final case class SchemaIndexScanUsage(identifier: String, labelId : Int, label: String, propertyKey: String) extends IndexUsage
final case class ExplicitNodeIndexUsage(identifier: String, index: String) extends IndexUsage final case class ExplicitNodeIndexUsage(identifier: String, index: String) extends IndexUsage
final case class ExplicitRelationshipIndexUsage(identifier: String, index: String) extends IndexUsage final case class ExplicitRelationshipIndexUsage(identifier: String, index: String) extends IndexUsage

object LogicalPlanId {
// This is probably a safe way of assigning ids, but should only be used in tests
private var counter = 0
def DEFAULT: LogicalPlanId = {
val id = new LogicalPlanId(counter)
counter += 1
id
}
}

class LogicalPlanId(val underlying: Int) extends AnyVal {
def ++ : LogicalPlanId = new LogicalPlanId(underlying + 1)

override def toString: String = s"id:$underlying"
}
Expand Up @@ -42,7 +42,7 @@ case object ProcedureCallOrSchemaCommandPlanBuilder extends Phase[CompilerContex
override def postConditions: Set[Condition] = Set.empty override def postConditions: Set[Condition] = Set.empty


override def process(from: BaseState, context: CompilerContext): LogicalPlanState = { override def process(from: BaseState, context: CompilerContext): LogicalPlanState = {
implicit val idGen = SequentialIdGen implicit val idGen = new SequentialIdGen()
val maybeLogicalPlan: Option[LogicalPlan] = from.statement() match { val maybeLogicalPlan: Option[LogicalPlan] = from.statement() match {
// Global call: CALL foo.bar.baz("arg1", 2) // Global call: CALL foo.bar.baz("arg1", 2)
case Query(None, SingleQuery(Seq(resolved@ResolvedCall(signature, args, _, _, _)))) => case Query(None, SingleQuery(Seq(resolved@ResolvedCall(signature, args, _, _, _)))) =>
Expand Down
Expand Up @@ -54,14 +54,13 @@ object DebugPrinter extends Phase[CompilerContext, LogicalPlanState, LogicalPlan
} }


private def stringToLogicalPlan(string: String): (LogicalPlan, Statement) = { private def stringToLogicalPlan(string: String): (LogicalPlan, Statement) = {
implicit val idGen = SequentialIdGen implicit val idGen = new SequentialIdGen()
val pos = InputPosition(0, 0, 0) val pos = InputPosition(0, 0, 0)
val solved = CardinalityEstimation.lift(RegularPlannerQuery(QueryGraph.empty), 0.0) val solved = CardinalityEstimation.lift(RegularPlannerQuery(QueryGraph.empty), 0.0)
val stringValues = string.split("\n").map(s => StringLiteral(s)(pos)) val stringValues = string.split("\n").map(s => StringLiteral(s)(pos))
val expression = ListLiteral(stringValues.toSeq)(pos) val expression = ListLiteral(stringValues.toSeq)(pos)
val unwind = UnwindCollection(Argument(Set.empty)(solved), IdName("col"), expression)(solved) val unwind = UnwindCollection(Argument(Set.empty)(solved), IdName("col"), expression)(solved)
val logicalPlan = ProduceResult(unwind, Seq("col")) val logicalPlan = ProduceResult(unwind, Seq("col"))
logicalPlan.assignIds()


val variable = Variable("col")(pos) val variable = Variable("col")(pos)
val returnItem = AliasedReturnItem(variable, variable)(pos) val returnItem = AliasedReturnItem(variable, variable)(pos)
Expand Down
Expand Up @@ -58,7 +58,6 @@ trait LogicalPlanRewriter extends Phase[CompilerContext, LogicalPlanState, Logic


override def process(from: LogicalPlanState, context: CompilerContext): LogicalPlanState = { override def process(from: LogicalPlanState, context: CompilerContext): LogicalPlanState = {
val rewritten = from.logicalPlan.endoRewrite(instance(context)) val rewritten = from.logicalPlan.endoRewrite(instance(context))
rewritten.assignIds() // This should be the only place where ids are assigned.
from.copy(maybeLogicalPlan = Some(rewritten)) from.copy(maybeLogicalPlan = Some(rewritten))
} }
} }
Expand Up @@ -38,7 +38,7 @@ import org.neo4j.cypher.internal.v3_4.logical.plans.{DeleteExpression => DeleteE
*/ */
case class LogicalPlanProducer(cardinalityModel: CardinalityModel, readTransactionLayer: Int) extends ListSupport { case class LogicalPlanProducer(cardinalityModel: CardinalityModel, readTransactionLayer: Int) extends ListSupport {


implicit val idGen = SequentialIdGen implicit val idGen = new SequentialIdGen()


def withNextTxLayer: LogicalPlanProducer = copy(readTransactionLayer = this.readTransactionLayer + 1) def withNextTxLayer: LogicalPlanProducer = copy(readTransactionLayer = this.readTransactionLayer + 1)


Expand Down
Expand Up @@ -26,7 +26,7 @@ import org.neo4j.cypher.internal.util.v3_4.attribution.SequentialIdGen
import scala.language.implicitConversions import scala.language.implicitConversions


trait LogicalPlanConstructionTestSupport extends CypherTestSupport { trait LogicalPlanConstructionTestSupport extends CypherTestSupport {
implicit val idGen = SequentialIdGen implicit val idGen = new SequentialIdGen()
implicit protected def idName(name: String): IdName = IdName(name) implicit protected def idName(name: String): IdName = IdName(name)
implicit protected def idSymbol(name: Symbol): IdName = IdName(name.name) implicit protected def idSymbol(name: Symbol): IdName = IdName(name.name)
} }
Expand Up @@ -33,7 +33,7 @@ import org.neo4j.cypher.internal.v3_4.logical.plans._


class PlanEventHorizonTest extends CypherFunSuite { class PlanEventHorizonTest extends CypherFunSuite {


implicit val idGen = SequentialIdGen implicit val idGen = new SequentialIdGen()


val pos = DummyPosition(1) val pos = DummyPosition(1)
val context = LogicalPlanningContext(mock[PlanContext], LogicalPlanProducer(mock[Metrics.CardinalityModel], LogicalPlan.LOWEST_TX_LAYER), val context = LogicalPlanningContext(mock[PlanContext], LogicalPlanProducer(mock[Metrics.CardinalityModel], LogicalPlan.LOWEST_TX_LAYER),
Expand Down
Expand Up @@ -26,26 +26,24 @@ import org.neo4j.cypher.internal.util.v3_4.{CypherException, Rewriter, topDown}
import org.neo4j.cypher.internal.v3_4.logical.plans.{NestedPlanExpression, _} import org.neo4j.cypher.internal.v3_4.logical.plans.{NestedPlanExpression, _}


class LogicalPlanAssignedIdTest extends CypherFunSuite with LogicalPlanningTestSupport2 { class LogicalPlanAssignedIdTest extends CypherFunSuite with LogicalPlanningTestSupport2 {
test("assignedId survives rewriting") { test("id survives rewriting") {
val sr1 = Argument()(solved) val sr1 = Argument()(solved)
val pr = Projection(sr1, Map.empty)(solved) val pr = Projection(sr1, Map.empty)(solved)
pr.assignIds()


val prPrim = pr.endoRewrite(topDown(Rewriter.lift { val prPrim = pr.endoRewrite(topDown(Rewriter.lift {
case sr: Argument => Argument()(solved) case sr: Argument => Argument()(solved)
})) }))


pr.assignedId should equal(prPrim.assignedId) pr.id should equal(prPrim.id)
pr.lhs.get.assignedId should equal(prPrim.lhs.get.assignedId) pr.lhs.get.id should equal(prPrim.lhs.get.id)
} }


test("assignedIds are different between plans") { test("ids are different between plans") {
val sr1 = Argument()(solved) val sr1 = Argument()(solved)
val sr2 = Argument()(solved) val sr2 = Argument()(solved)
val apply = Apply(sr1, sr2)(solved) val apply = Apply(sr1, sr2)(solved)
apply.assignIds()


sr1.assignedId shouldNot equal(sr2.assignedId) sr1.id shouldNot equal(sr2.id)
} }


test("tree structure is assigned ids in a predictable way") { test("tree structure is assigned ids in a predictable way") {
Expand All @@ -62,32 +60,12 @@ class LogicalPlanAssignedIdTest extends CypherFunSuite with LogicalPlanningTestS
val applyB = Apply(sr1B, sr2B)(solved) val applyB = Apply(sr1B, sr2B)(solved)
val applyAll = Apply(applyA, applyB)(solved) // I heard you guys like Apply, so we applied an Apply in your Apply val applyAll = Apply(applyA, applyB)(solved) // I heard you guys like Apply, so we applied an Apply in your Apply


applyAll.assignIds() applyAll.id.x should equal(0)

applyA.id.x should equal(1)
applyAll.assignedId.underlying should equal(0) sr1A.id.x should equal(2)
applyA.assignedId.underlying should equal(1) sr2A.id.x should equal(3)
sr1A.assignedId.underlying should equal(2) applyB.id.x should equal(4)
sr2A.assignedId.underlying should equal(3) sr1B.id.x should equal(5)
applyB.assignedId.underlying should equal(4) sr2B.id.x should equal(6)
sr1B.assignedId.underlying should equal(5)
sr2B.assignedId.underlying should equal(6)
}

test("cant assign ids twice") {
val sr1 = Argument()(solved)
val pr = Projection(sr1, Map.empty)(solved)
pr.assignIds()
intercept[CypherException](pr.assignIds())
} }

test("can assign inside expressions as well") {
val argument = Argument()(solved)
val inner = AllNodesScan(IdName("x"), Set.empty)(solved)
val filter = Selection(Seq(NestedPlanExpression(inner, literalInt(42))(pos)), argument)(solved)

filter.assignIds()

val x = inner.assignedId // should not fail
}

} }
Expand Up @@ -34,8 +34,8 @@ import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription
import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription.Arguments._ import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription.Arguments._
import org.neo4j.cypher.internal.runtime.planDescription.{Children, NoChildren, PlanDescriptionImpl, SingleChild, TwoChildren, Argument => Argument3_4, InternalPlanDescription => InternalPlanDescription3_4} import org.neo4j.cypher.internal.runtime.planDescription.{Children, NoChildren, PlanDescriptionImpl, SingleChild, TwoChildren, Argument => Argument3_4, InternalPlanDescription => InternalPlanDescription3_4}
import org.neo4j.cypher.internal.runtime.{QueryStatistics, SCHEMA_WRITE, ExecutionMode => ExecutionModeV3_4, _} import org.neo4j.cypher.internal.runtime.{QueryStatistics, SCHEMA_WRITE, ExecutionMode => ExecutionModeV3_4, _}
import org.neo4j.cypher.internal.util.v3_4.attribution.Id
import org.neo4j.cypher.internal.v3_4.expressions.SemanticDirection.{BOTH, INCOMING, OUTGOING} import org.neo4j.cypher.internal.v3_4.expressions.SemanticDirection.{BOTH, INCOMING, OUTGOING}
import org.neo4j.cypher.internal.v3_4.logical.plans.LogicalPlanId
import org.neo4j.cypher.result.QueryResult import org.neo4j.cypher.result.QueryResult
import org.neo4j.cypher.result.QueryResult.Record import org.neo4j.cypher.result.QueryResult.Record
import org.neo4j.graphdb.Result.ResultVisitor import org.neo4j.graphdb.Result.ResultVisitor
Expand Down Expand Up @@ -194,7 +194,7 @@ class ExecutionResultWrapper(val inner: InternalExecutionResult, val planner: Pl
case planDescriptionv2_3.InternalPlanDescription.Arguments.SourceCode(className, sourceCode) => case planDescriptionv2_3.InternalPlanDescription.Arguments.SourceCode(className, sourceCode) =>
Arguments.SourceCode(className, sourceCode) Arguments.SourceCode(className, sourceCode)
} }
PlanDescriptionImpl(LogicalPlanId.DEFAULT, name, children, arguments, planDescription.identifiers) PlanDescriptionImpl(Id.INVALID_ID, name, children, arguments, planDescription.identifiers)
} }


override def hasNext: Boolean = inner.hasNext override def hasNext: Boolean = inner.hasNext
Expand Down
Expand Up @@ -36,9 +36,10 @@ import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription
import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription.Arguments._ import org.neo4j.cypher.internal.runtime.planDescription.InternalPlanDescription.Arguments._
import org.neo4j.cypher.internal.runtime.planDescription.{Argument, Children, NoChildren, PlanDescriptionImpl, SingleChild, TwoChildren, InternalPlanDescription => InternalPlanDescription3_4} import org.neo4j.cypher.internal.runtime.planDescription.{Argument, Children, NoChildren, PlanDescriptionImpl, SingleChild, TwoChildren, InternalPlanDescription => InternalPlanDescription3_4}
import org.neo4j.cypher.internal.runtime.{ExplainMode, NormalMode, ProfileMode, QueryStatistics} import org.neo4j.cypher.internal.runtime.{ExplainMode, NormalMode, ProfileMode, QueryStatistics}
import org.neo4j.cypher.internal.util.v3_4.attribution.Id
import org.neo4j.cypher.internal.util.v3_4.{symbols => symbolsv3_4} import org.neo4j.cypher.internal.util.v3_4.{symbols => symbolsv3_4}
import org.neo4j.cypher.internal.v3_4.expressions.SemanticDirection.{BOTH, INCOMING, OUTGOING} import org.neo4j.cypher.internal.v3_4.expressions.SemanticDirection.{BOTH, INCOMING, OUTGOING}
import org.neo4j.cypher.internal.v3_4.logical.plans.{LogicalPlanId, QualifiedName} import org.neo4j.cypher.internal.v3_4.logical.plans.QualifiedName
import org.neo4j.cypher.result.QueryResult import org.neo4j.cypher.result.QueryResult
import org.neo4j.cypher.result.QueryResult.Record import org.neo4j.cypher.result.QueryResult.Record
import org.neo4j.graphdb import org.neo4j.graphdb
Expand Down Expand Up @@ -145,7 +146,7 @@ class ExecutionResultWrapper(val inner: InternalExecutionResult, val planner: Pl
val procName = QualifiedName(procedureName.namespace, procedureName.name) val procName = QualifiedName(procedureName.namespace, procedureName.name)
Arguments.Signature(procName, Seq.empty, results.map(pair => (pair._1, lift(pair._2)))) Arguments.Signature(procName, Seq.empty, results.map(pair => (pair._1, lift(pair._2))))
} }
PlanDescriptionImpl(LogicalPlanId.DEFAULT, name, children, arguments, planDescription.variables) PlanDescriptionImpl(Id.INVALID_ID, name, children, arguments, planDescription.variables)
} }


private def lift(cypherType: symbols3_1.CypherType): symbolsv3_4.CypherType = cypherType match { private def lift(cypherType: symbols3_1.CypherType): symbolsv3_4.CypherType = cypherType match {
Expand Down
Expand Up @@ -38,7 +38,7 @@ import org.neo4j.cypher.internal.v3_4.logical.plans.{LogicalPlan => LogicalPlanV
import org.neo4j.cypher.internal.v3_4.logical.{plans => plansV3_4} import org.neo4j.cypher.internal.v3_4.logical.{plans => plansV3_4}
import org.neo4j.cypher.internal.v3_4.{expressions => expressionsV3_4} import org.neo4j.cypher.internal.v3_4.{expressions => expressionsV3_4}
import org.neo4j.cypher.internal.compiler.{v3_3 => compilerV3_3} import org.neo4j.cypher.internal.compiler.{v3_3 => compilerV3_3}
import org.neo4j.cypher.internal.util.v3_4.attribution.{IdGen, SequentialIdGen} import org.neo4j.cypher.internal.util.v3_4.attribution.{Id, IdGen, SameId, SequentialIdGen}


import scala.collection.mutable import scala.collection.mutable
import scala.collection.mutable.{HashMap => MutableHashMap} import scala.collection.mutable.{HashMap => MutableHashMap}
Expand All @@ -55,27 +55,25 @@ object LogicalPlanConverter {
override def apply(v1: (AnyRef, Seq[AnyRef])): AnyRef = rewriter.apply(v1) override def apply(v1: (AnyRef, Seq[AnyRef])): AnyRef = rewriter.apply(v1)


private val rewriter: RewriterWithArgs = bottomUpWithArgs { before => private val rewriter: RewriterWithArgs = bottomUpWithArgs { before =>
implicit val idGen = SequentialIdGen

val rewritten = RewriterWithArgs.lift { val rewritten = RewriterWithArgs.lift {
case (plan: plansV3_3.Argument, children: Seq[AnyRef]) => case (plan: plansV3_3.Argument, children: Seq[AnyRef]) =>
plansV3_4.Argument(children.head.asInstanceOf[Set[IdNameV3_4]])(new PlannerQueryWrapper(plan.solved)) plansV3_4.Argument(children.head.asInstanceOf[Set[IdNameV3_4]])(new PlannerQueryWrapper(plan.solved))(SameId(Id(plan.assignedId.underlying)))
case (plan: plansV3_3.SingleRow, _) => case (plan: plansV3_3.SingleRow, _) =>
plansV3_4.Argument()(new PlannerQueryWrapper(plan.solved)) plansV3_4.Argument()(new PlannerQueryWrapper(plan.solved))(SameId(Id(plan.assignedId.underlying)))
case (_: plansV3_3.ProduceResult, children: Seq[AnyRef]) => case (plan: plansV3_3.ProduceResult, children: Seq[AnyRef]) =>
plansV3_4.ProduceResult(source = children(1).asInstanceOf[LogicalPlanV3_4], plansV3_4.ProduceResult(source = children(1).asInstanceOf[LogicalPlanV3_4],
columns = children(0).asInstanceOf[Seq[String]]) columns = children(0).asInstanceOf[Seq[String]])(SameId(Id(plan.assignedId.underlying)))
case (plan: plansV3_3.TriadicSelection, children: Seq[AnyRef]) => case (plan: plansV3_3.TriadicSelection, children: Seq[AnyRef]) =>
plansV3_4.TriadicSelection(left = children(1).asInstanceOf[LogicalPlanV3_4], plansV3_4.TriadicSelection(left = children(1).asInstanceOf[LogicalPlanV3_4],
right = children(5).asInstanceOf[LogicalPlanV3_4], right = children(5).asInstanceOf[LogicalPlanV3_4],
positivePredicate = children(0).asInstanceOf[Boolean], positivePredicate = children(0).asInstanceOf[Boolean],
sourceId = children(2).asInstanceOf[IdNameV3_4], sourceId = children(2).asInstanceOf[IdNameV3_4],
seenId = children(3).asInstanceOf[IdNameV3_4], seenId = children(3).asInstanceOf[IdNameV3_4],
targetId = children(4).asInstanceOf[IdNameV3_4])(new PlannerQueryWrapper(plan.solved)) targetId = children(4).asInstanceOf[IdNameV3_4])(new PlannerQueryWrapper(plan.solved))(SameId(Id(plan.assignedId.underlying)))
case (plan: plansV3_3.ProceduralLogicalPlan, children: Seq[AnyRef]) => case (plan: plansV3_3.ProceduralLogicalPlan, children: Seq[AnyRef]) =>
convertVersion("v3_3", "v3_4", plan, children, idGen, classOf[IdGen]) convertVersion("v3_3", "v3_4", plan, children, SameId(Id(plan.assignedId.underlying)), classOf[IdGen])
case (plan: plansV3_3.LogicalPlan, children: Seq[AnyRef]) => case (plan: plansV3_3.LogicalPlan, children: Seq[AnyRef]) =>
convertVersion("v3_3", "v3_4", plan, children, new PlannerQueryWrapper(plan.solved), classOf[PlannerQuery], idGen, classOf[IdGen]) convertVersion("v3_3", "v3_4", plan, children, new PlannerQueryWrapper(plan.solved), classOf[PlannerQuery], SameId(Id(plan.assignedId.underlying)), classOf[IdGen])


case (inp: astV3_3.InvalidNodePattern, children: Seq[AnyRef]) => case (inp: astV3_3.InvalidNodePattern, children: Seq[AnyRef]) =>
new expressionsV3_4.InvalidNodePattern(children.head.asInstanceOf[Option[expressionsV3_4.Variable]].get)(helpers.as3_4(inp.position)) new expressionsV3_4.InvalidNodePattern(children.head.asInstanceOf[Option[expressionsV3_4.Variable]].get)(helpers.as3_4(inp.position))
Expand Down Expand Up @@ -164,7 +162,6 @@ object LogicalPlanConverter {
case plan: LogicalPlanV3_3 => case plan: LogicalPlanV3_3 =>
try { try {
val plan3_4 = rewritten.asInstanceOf[LogicalPlanV3_4] val plan3_4 = rewritten.asInstanceOf[LogicalPlanV3_4]
plan3_4.setIdTo(helpers.as3_4(plan.assignedId))
// 3.3 does not know about transaction layers, it plans Eagers instead. // 3.3 does not know about transaction layers, it plans Eagers instead.
plan3_4.readTransactionLayer.value = 0 plan3_4.readTransactionLayer.value = 0
} catch { } catch {
Expand Down
Expand Up @@ -38,9 +38,9 @@ import org.neo4j.cypher.internal.frontend.v3_4.{phases => phasesV3_4}
import org.neo4j.cypher.internal.ir.v3_3.{Cardinality => CardinalityV3_3} import org.neo4j.cypher.internal.ir.v3_3.{Cardinality => CardinalityV3_3}
import org.neo4j.cypher.internal.ir.{v3_3 => irV3_3, v3_4 => irV3_4} import org.neo4j.cypher.internal.ir.{v3_3 => irV3_3, v3_4 => irV3_4}
import org.neo4j.cypher.internal.planner.v3_4.spi.{DPPlannerName, IDPPlannerName, PlannerNameWithVersion, ProcedurePlannerName} import org.neo4j.cypher.internal.planner.v3_4.spi.{DPPlannerName, IDPPlannerName, PlannerNameWithVersion, ProcedurePlannerName}
import org.neo4j.cypher.internal.util.v3_4.attribution.Id
import org.neo4j.cypher.internal.util.v3_4.{Cardinality, InputPosition} import org.neo4j.cypher.internal.util.v3_4.{Cardinality, InputPosition}
import org.neo4j.cypher.internal.v3_3.logical.plans.{LogicalPlanId => LogicalPlanIdV3_3} import org.neo4j.cypher.internal.v3_3.logical.plans.{LogicalPlanId => LogicalPlanIdV3_3}
import org.neo4j.cypher.internal.v3_4.logical.plans.{LogicalPlanId => LogicalPlanIdV3_4}
import org.neo4j.kernel.impl.query.{QueryExecutionMonitor, TransactionalContext} import org.neo4j.kernel.impl.query.{QueryExecutionMonitor, TransactionalContext}


object helpers { object helpers {
Expand Down Expand Up @@ -97,7 +97,7 @@ object helpers {


def as3_4(pos: InputPositionV3_3): InputPosition = if(pos == null) null else InputPosition(pos.offset, pos.line, pos.column) def as3_4(pos: InputPositionV3_3): InputPosition = if(pos == null) null else InputPosition(pos.offset, pos.line, pos.column)


def as3_4(planId: LogicalPlanIdV3_3) : LogicalPlanIdV3_4 = new LogicalPlanIdV3_4(planId.underlying) def as3_4(planId: LogicalPlanIdV3_3) : Id = Id(planId.underlying)


def as3_4(plannerName: PlannerNameV3_3) : PlannerName = plannerName match { def as3_4(plannerName: PlannerNameV3_3) : PlannerName = plannerName match {
case IDPPlannerNameV3_3 => IDPPlannerName case IDPPlannerNameV3_3 => IDPPlannerName
Expand Down

0 comments on commit 3160a5a

Please sign in to comment.