Commit 5430f47e authored by Davide Grohmann's avatar Davide Grohmann
Browse files

Use the introduced rewriter in Ronja

o remove code which was needed for handling equals
o cleanup on normalizeEqualsArgumentOrder
parent de3d5ea0
No related merge requests found
Showing with 131 additions and 230 deletions
+131 -230
......@@ -27,28 +27,28 @@ class ASTRewriter(rewritingMonitor: AstRewritingMonitor, shouldExtractParameters
def rewrite(queryText: String, statement: Statement): (Statement, Map[String, Any]) = {
rewritingMonitor.startRewriting(queryText, statement)
val (extractParameters: Rewriter, extractedParameters: Map[String, Any]) = literalReplacement(statement)
val rewriters = Seq.newBuilder[Rewriter]
rewriters += foldConstants
if (shouldExtractParameters)
rewriters += extractParameters
rewriters += nameMatchPatternElements
rewriters += normalizeMatchPredicates
rewriters += normalizeNotEquals
rewriters += normalizeEqualsArgumentOrder
rewriters += reattachAliasedExpressions
rewriters += addUniquenessPredicates
rewriters += expandStar
rewriters += isolateAggregation
rewriters += aliasReturnItems
val rewriter = inSequence(rewriters.result(): _*)
val (extractParameters, extractedParameters) = if (shouldExtractParameters)
literalReplacement(statement)
else
(Rewriter.lift(PartialFunction.empty), Map.empty[String, Any])
val rewriters = Seq(
foldConstants,
extractParameters,
nameMatchPatternElements,
normalizeMatchPredicates,
normalizeNotEquals,
normalizeEqualsArgumentOrder,
reattachAliasedExpressions,
addUniquenessPredicates,
expandStar,
isolateAggregation,
aliasReturnItems)
val rewriter = inSequence(rewriters: _*)
val rewrittenStatement = statement.rewrite(rewriter).asInstanceOf[ast.Statement]
rewritingMonitor.finishRewriting(queryText, rewrittenStatement)
(rewrittenStatement, if (shouldExtractParameters) extractedParameters else Map.empty)
(rewrittenStatement, extractedParameters)
}
}
......@@ -19,23 +19,23 @@
*/
package org.neo4j.cypher.internal.compiler.v2_1.ast.rewriters
import org.neo4j.cypher.internal.compiler.v2_1.{topDown, Rewriter}
import org.neo4j.cypher.internal.compiler.v2_1.ast.{FunctionName, FunctionInvocation, Identifier, Equals}
import org.neo4j.cypher.internal.compiler.v2_1._
import org.neo4j.cypher.internal.compiler.v2_1.ast._
object normalizeEqualsArgumentOrder extends Rewriter {
override def apply(that: AnyRef): Option[AnyRef] = topDown(instance).apply(that)
private val instance: Rewriter = Rewriter.lift {
// moved identifiers on equals to the left
case predicate @ Equals(Identifier(_), _) =>
// move n.prop on equals to the left
case predicate @ Equals(Property(_, _), _) =>
predicate
case predicate @ Equals(lhs, rhs @ Identifier(_)) =>
case predicate @ Equals(lhs, rhs @ Property(_, _)) =>
predicate.copy(lhs = rhs, rhs = lhs)(predicate.position)
// move id(n) on equals to the left
case predicate @ Equals(FunctionInvocation(FunctionName("id"), _, _), _) =>
case predicate @ Equals(func@FunctionInvocation(_, _, _), _) if func.function == Some(functions.Id) =>
predicate
case predicate @ Equals(lhs, rhs @ FunctionInvocation(FunctionName("id"), _, _)) =>
case predicate @ Equals(lhs, rhs @ FunctionInvocation(_, _, _)) if rhs.function == Some(functions.Id) =>
predicate.copy(lhs = rhs, rhs = lhs)(predicate.position)
}
}
......@@ -24,7 +24,7 @@ import org.neo4j.cypher.internal.compiler.v2_1.executionplan.PipeBuilder
import org.neo4j.cypher.internal.compiler.v2_1.planner.logical._
import org.neo4j.cypher.internal.compiler.v2_1.planner.execution.PipeExecutionPlanBuilder
import org.neo4j.cypher.internal.compiler.v2_1.spi.PlanContext
import org.neo4j.cypher.internal.compiler.v2_1.{inSequence, bottomUp, ParsedQuery, Monitors}
import org.neo4j.cypher.internal.compiler.v2_1.{bottomUp, inSequence, ParsedQuery, Monitors}
import org.neo4j.cypher.internal.compiler.v2_1.executionplan.PipeInfo
import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.plans.{QueryPlan, LogicalPlan}
import org.neo4j.cypher.internal.compiler.v2_1.ast.rewriters._
......@@ -73,13 +73,19 @@ case class Planner(monitors: Monitors,
object Planner {
def rewriteStatement(statement: Statement): Statement = {
val cnfStatement = statement.typedRewrite[Statement](CNFNormalizer)
val namedStatement = cnfStatement.typedRewrite[Statement](bottomUp(
inSequence(nameVarLengthRelationships, namePatternPredicates)
))
val rewrittenStatement = statement.typedRewrite[Statement](
inSequence(
rewriteEqualityToInCollection,
splitInCollectionsToIsolateConstants,
CNFNormalizer,
collapseInCollectionsContainingConstants,
nameVarLengthRelationships,
namePatternPredicates
)
)
val statementWithInlinedProjections = inlineProjections(namedStatement)
val statementWithAliasedSortSkipAndLimit = statementWithInlinedProjections.typedRewrite[Statement](bottomUp(useAliasesInSortSkipAndLimit))
val statementWithInlinedProjections = inlineProjections(rewrittenStatement)
val statementWithAliasedSortSkipAndLimit = statementWithInlinedProjections.typedRewrite[Statement](useAliasesInSortSkipAndLimit)
statementWithAliasedSortSkipAndLimit
}
......
......@@ -23,9 +23,9 @@ import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.plans._
import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.plans.SingleRow
import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.plans.NodeIndexSeek
import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.plans.AllNodesScan
import Metrics._
import org.neo4j.cypher.internal.compiler.v2_1.commands.{ManyQueryExpression, SingleQueryExpression}
import org.neo4j.cypher.internal.compiler.v2_1.ast.Collection
import org.neo4j.cypher.internal.compiler.v2_1.commands.{ManyQueryExpression, SingleQueryExpression}
import Metrics._
class SimpleCostModel(cardinality: CardinalityModel) extends CostModel {
......
......@@ -53,9 +53,6 @@ abstract class IndexLeafPlanner extends LeafPlanner {
CandidateList(
predicates.collect {
case equalityPredicate@Equals(Property(identifier@Identifier(name), propertyKeyName), ConstantExpression(valueExpr)) =>
producePlanFor(name, propertyKeyName, equalityPredicate, SingleQueryExpression(valueExpr))
case inPredicate@In(Property(identifier@Identifier(name), propertyKeyName), ConstantExpression(valueExpr)) =>
producePlanFor(name, propertyKeyName, inPredicate, ManyQueryExpression(valueExpr))
}.flatten
......
......@@ -33,12 +33,6 @@ object idSeekLeafPlanner extends LeafPlanner {
val predicates: Seq[Expression] = qg.selections.flatPredicates
val candidatePlans = predicates.collect {
// MATCH (a)-[r]->b WHERE id(r) = value
// MATCH a WHERE id(a) = value
case predicate@Equals(func@FunctionInvocation(_, _, IndexedSeq(idExpr)), ConstantExpression(idValueExpr))
if func.function == Some(functions.Id) =>
(predicate, idExpr, Seq(idValueExpr))
// MATCH (a)-[r]->b WHERE id(r) IN value
// MATCH a WHERE id(a) IN value
case predicate@In(func@FunctionInvocation(_, _, IndexedSeq(idExpr)), idsExpr@Collection(idValueExprs))
......
......@@ -20,41 +20,52 @@
package org.neo4j.cypher.internal.compiler.v2_1.ast.rewriters
import org.neo4j.cypher.internal.commons.CypherFunSuite
import org.neo4j.cypher.internal.compiler.v2_1.DummyPosition
import org.neo4j.cypher.internal.compiler.v2_1.{InputPosition, DummyPosition}
import org.neo4j.cypher.internal.compiler.v2_1.ast._
import org.neo4j.cypher.internal.compiler.v2_1.ast.Equals
import org.neo4j.cypher.internal.compiler.v2_1.ast.Identifier
import org.neo4j.cypher.internal.compiler.v2_1.ast.SignedIntegerLiteral
class NormalizeEqualsArgumentOrderTest extends CypherFunSuite {
class NormalizeEqualsArgumentOrderTest extends CypherFunSuite with AstConstructionTestSupport {
val pos = DummyPosition(0)
test("a.prop = b.prop rewritten to: a.prop = b.prop") {
val lhs: Expression = Property(ident("a"), PropertyKeyName("prop")_)_
val rhs: Expression = Property(ident("b"), PropertyKeyName("prop")_)_
test("a = b rewritten to: a = b") {
val input = Equals(Identifier("a")(pos), Identifier("b")(pos))(pos)
val input: Expression = Equals(lhs, rhs)_
normalizeEqualsArgumentOrder(input) should equal(Some(input))
}
test("12 = a rewritten to: a = 12") {
val lhs = SignedIntegerLiteral("12")(pos)
val rhs = Identifier("a")(pos)
test("12 = a.prop rewritten to: a.prop = 12") {
val lhs: Expression = SignedIntegerLiteral("12")_
val rhs: Expression = Property(ident("a"), PropertyKeyName("prop")_)_
normalizeEqualsArgumentOrder(Equals(lhs, rhs)(pos)) should equal(Some(Equals(rhs, lhs)(pos)))
val input: Expression = Equals(lhs, rhs)_
val expected: Expression = Equals(rhs, lhs)_
normalizeEqualsArgumentOrder(input) should equal(Some(expected))
}
test("id(a) = id(b) rewritten to: id(a) = id(b)") {
val input = Equals(id("a"), id("b"))(pos)
val lhs: Expression = id("a")
val rhs: Expression = id("b")
val input: Expression = Equals(lhs, rhs)_
normalizeEqualsArgumentOrder(input) should equal(Some(input))
}
test("23 = id(a) rewritten to: id(a) = 23") {
val lhs = SignedIntegerLiteral("12")(pos)
val rhs = id("a")
val lhs: Expression = SignedIntegerLiteral("12")_
val rhs: Expression = id("a")
val input: Expression = Equals(lhs, rhs)_
val expected: Expression = Equals(rhs, lhs)_
normalizeEqualsArgumentOrder(Equals(lhs, rhs)(pos)) should equal(Some(Equals(rhs, lhs)(pos)))
normalizeEqualsArgumentOrder(input) should equal(Some(expected))
}
private def id(name: String) = FunctionInvocation(FunctionName("id")(pos), distinct = false, Array(Identifier(name)(pos)))(pos)
private def id(name: String): FunctionInvocation =
FunctionInvocation(FunctionName("id")(pos), distinct = false, Array(Identifier(name)(pos)))(pos)
}
......@@ -43,9 +43,7 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
val ast = parser.parse(query)
val rewrittenAst: Statement = if (normalize) {
val step1 = astRewriter.rewrite(query, ast)._1
val step2 = Planner.rewriteStatement(step1)
inlineProjections(step2)
Planner.rewriteStatement(astRewriter.rewrite(query, ast)._1)
} else {
ast
}
......@@ -169,9 +167,9 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
query.graph.selections should equal(Selections(Set(
Predicate(Set(IdName("n")), HasLabels(nIdent, Seq(A))_),
Predicate(Set(IdName("n")), Equals(
Predicate(Set(IdName("n")), In(
FunctionInvocation(FunctionName("id")_, distinct = false, Vector(Identifier("n")(pos)))(pos),
SignedIntegerLiteral("42")_
Collection(Seq(SignedIntegerLiteral("42")_))_
)_
))))
......@@ -485,9 +483,9 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
NodePattern(Some(Identifier(nodeName)(pos)), Seq(), None, naked = false) _
) _) _)
val relationship = PatternRelationship(IdName(relName), (IdName("a"), IdName(nodeName)), Direction.OUTGOING, Seq.empty, SimplePatternLength)
val exp2: Expression = Equals(
val exp2: Expression = In(
Property(Identifier("a")_, PropertyKeyName("prop")_)_,
SignedIntegerLiteral("42")_
Collection(Seq(SignedIntegerLiteral("42")_))_
)_
val orPredicate = Predicate(Set(IdName("a")), Ors(Set(exp1, exp2))_)
val subQueriesTable = Map(exp1 ->
......@@ -516,9 +514,9 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
NodePattern(Some(Identifier(nodeName)(pos)), Seq(), None, naked = false) _
) _) _)
val relationship = PatternRelationship(IdName(relName), (IdName("a"), IdName(nodeName)), Direction.OUTGOING, Seq.empty, SimplePatternLength)
val exp2: Expression = Equals(
Property(Identifier("a") _, PropertyKeyName("prop")_)_,
SignedIntegerLiteral("42") _
val exp2: Expression = In(
Property(Identifier("a")_, PropertyKeyName("prop")_)_,
Collection(Seq(SignedIntegerLiteral("42")_))_
) _
val orPredicate = Predicate(Set(IdName("a")), Ors(Set(exp1, exp2))_)
val subQueriesTable = Map(exp1 ->
......@@ -534,26 +532,26 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
lookupTable should equal(subQueriesTable)
}
test("match a where a.prop = 21 OR (a)-->() OR a.prop = 42 return a") {
test("match a where a.prop2 = 21 OR (a)-->() OR a.prop = 42 return a") {
// Given
val (query, lookupTable) = buildPlannerQuery("match a where a.prop = 21 OR (a)-->() OR a.prop = 42 return a", normalize = true)
val (query, lookupTable) = buildPlannerQuery("match a where a.prop2 = 21 OR (a)-->() OR a.prop = 42 return a", normalize = true)
// Then inner pattern query graph
val relName = " UNNAMED32"
val nodeName = " UNNAMED36"
val relName = " UNNAMED33"
val nodeName = " UNNAMED37"
val exp1: PatternExpression = PatternExpression(RelationshipsPattern(RelationshipChain(
NodePattern(Some(Identifier("a")(pos)), Seq(), None, naked = false) _,
RelationshipPattern(Some(Identifier(relName)(pos)), optional = false, Seq.empty, None, None, Direction.OUTGOING) _,
NodePattern(Some(Identifier(nodeName)(pos)), Seq(), None, naked = false) _
) _) _)
val relationship = PatternRelationship(IdName(relName), (IdName("a"), IdName(nodeName)), Direction.OUTGOING, Seq.empty, SimplePatternLength)
val exp2: Expression = Equals(
Property(Identifier("a") _, PropertyKeyName("prop")_)_,
SignedIntegerLiteral("42")_
val exp2: Expression = In(
Property(Identifier("a")_, PropertyKeyName("prop")_)_,
Collection(Seq(SignedIntegerLiteral("42")_))_
)_
val exp3: Expression = Equals(
Property(Identifier("a") _, PropertyKeyName("prop")_)_,
SignedIntegerLiteral("21")_
val exp3: Expression = In(
Property(Identifier("a")_, PropertyKeyName("prop2")_)_,
Collection(Seq(SignedIntegerLiteral("21")_))_
)_
val orPredicate = Predicate(Set(IdName("a")), Ors(Set(exp1, exp3, exp2))_)
val subQueriesTable = Map(exp1 ->
......@@ -658,7 +656,7 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
tailQg.graph.selections.predicates should equal(Set(
Predicate(
Set(IdName("b"), IdName("a")),
Equals(Property(Identifier("a")_, PropertyKeyName("prop")_)_, FunctionInvocation(FunctionName("id")_, Identifier("b")_)_)_
Equals(FunctionInvocation(FunctionName("id")_, Identifier("b")_)_, Property(Identifier("a")_, PropertyKeyName("prop")_)_)_
)
))
tailQg.projection.projections should equal(Map[String, Expression]("b" -> Identifier("b")_))
......@@ -671,7 +669,7 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
Predicate(Set(IdName("a")), HasLabels(Identifier("a")_, Seq(LabelName("Start")(null)))_),
Predicate(
Set(IdName("b"), IdName("a")),
Equals(Property(Identifier("a")_, PropertyKeyName("prop")_)_, FunctionInvocation(FunctionName("id")_, Identifier("b")_)_)_
Equals(FunctionInvocation(FunctionName("id")_, Identifier("b")_)_, Property(Identifier("a")_, PropertyKeyName("prop")_)_)_
)
))
query.graph.patternNodes should equal(Set(IdName("a"), IdName("b")))
......@@ -698,7 +696,7 @@ class SimplePlannerQueryBuilderTest extends CypherFunSuite with LogicalPlanningT
tailQg.graph.selections.predicates should equal(Set(
Predicate(
Set(IdName("b"), IdName("property")),
Equals(Identifier("property")_, FunctionInvocation(FunctionName("id")_, Identifier("b")_)_)_
Equals(FunctionInvocation(FunctionName("id")_, Identifier("b")_)_, Identifier("property")_)_
)
))
tailQg.projection.projections should equal(Map[String, Expression]("b" -> Identifier("b")_))
......
......@@ -26,7 +26,7 @@ import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.plans._
import org.neo4j.cypher.internal.compiler.v2_1.planner.BeLikeMatcher._
import org.neo4j.cypher.internal.compiler.v2_1.ast._
import org.neo4j.cypher.internal.compiler.v2_1.{PropertyKeyId, LabelId}
import org.neo4j.cypher.internal.compiler.v2_1.commands.SingleQueryExpression
import org.neo4j.cypher.internal.compiler.v2_1.commands.{ManyQueryExpression, SingleQueryExpression}
class ExpandPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTestSupport2 {
......@@ -111,7 +111,7 @@ class ExpandPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningT
Projection(
Expand(
Selection(
Seq(Equals(Property(Identifier("a")_, PropertyKeyName("name")_)_, StringLiteral("Andres")_)_),
Seq(In(Property(Identifier("a")_, PropertyKeyName("name")_)_, Collection(Seq(StringLiteral("Andres")_))_)_),
AllNodesScan("a")
),
"a", Direction.BOTH, Seq(RelTypeName("x")_), "start", "rel", SimplePatternLength
......@@ -132,7 +132,7 @@ class ExpandPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningT
} planFor "MATCH (a)-[r]->(b) USING INDEX b:Person(name) WHERE b:Person AND b.name = 'Andres' return r").plan should equal(
Projection(
Expand(
NodeIndexSeek("b", LabelToken("Person", LabelId(0)), PropertyKeyToken("name", PropertyKeyId(0)), SingleQueryExpression(StringLiteral("Andres")_)),
NodeIndexSeek("b", LabelToken("Person", LabelId(0)), PropertyKeyToken("name", PropertyKeyId(0)), ManyQueryExpression(Collection(Seq(StringLiteral("Andres")_))_)),
"b", Direction.INCOMING, Seq.empty, "a", "r", SimplePatternLength
),
Map("r" -> ident("r"))
......@@ -154,13 +154,13 @@ class ExpandPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningT
NodeHashJoin(
"b",
Selection(
Seq(Equals(Property(ident("b"), PropertyKeyName("name")_)_, StringLiteral("Andres")_)_, HasLabels(ident("b"), Seq(LabelName("Person")_))_),
Seq(In(Property(ident("b"), PropertyKeyName("name")_)_, Collection(Seq(StringLiteral("Andres")_))_)_, HasLabels(ident("b"), Seq(LabelName("Person")_))_),
Expand(
NodeIndexSeek("a", LabelToken("Person", LabelId(0)), PropertyKeyToken("name", PropertyKeyId(0)), SingleQueryExpression(StringLiteral("Jakub")_)),
NodeIndexSeek("a", LabelToken("Person", LabelId(0)), PropertyKeyToken("name", PropertyKeyId(0)), ManyQueryExpression(Collection(Seq(StringLiteral("Jakub")_))_)),
"a", Direction.OUTGOING, Seq.empty, "b", "r", SimplePatternLength
)
),
NodeIndexSeek("b", LabelToken("Person", LabelId(0)), PropertyKeyToken("name", PropertyKeyId(0)), SingleQueryExpression(StringLiteral("Andres")_))
NodeIndexSeek("b", LabelToken("Person", LabelId(0)), PropertyKeyToken("name", PropertyKeyId(0)), ManyQueryExpression(Collection(Seq(StringLiteral("Andres")_))_))
),
Map("r" -> ident("r"))
)
......
......@@ -24,8 +24,8 @@ import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.plans._
import org.neo4j.cypher.internal.compiler.v2_1.ast._
import org.neo4j.cypher.internal.compiler.v2_1.planner.LogicalPlanningTestSupport2
import org.neo4j.cypher.internal.compiler.v2_1.{PropertyKeyId, LabelId}
import org.neo4j.cypher.internal.compiler.v2_1.commands.{ManyQueryExpression, SingleQueryExpression}
import org.neo4j.cypher.internal.compiler.v2_1.planner.BeLikeMatcher._
import org.neo4j.cypher.internal.compiler.v2_1.commands.{ManyQueryExpression, SingleQueryExpression}
class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTestSupport2 {
......@@ -79,7 +79,7 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
"n",
LabelToken("Awesome", LabelId(0)),
PropertyKeyToken(PropertyKeyName("prop")_, PropertyKeyId(0)),
SingleQueryExpression(SignedIntegerLiteral("42")(pos))
ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")_))_)
)
)
}
......@@ -90,7 +90,7 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
} planFor "MATCH (n:Awesome) WHERE n.prop = 42 RETURN n"
plan.plan should equal(
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), SingleQueryExpression(SignedIntegerLiteral("42")_))
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")_))_))
)
}
......@@ -101,7 +101,7 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
} planFor "MATCH (n:Awesome) WHERE n.prop = 42 RETURN n"
plan.plan should equal(
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(1)), SingleQueryExpression(SignedIntegerLiteral("42")_))
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(1)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")_))_))
)
}
......@@ -178,7 +178,7 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
} planFor "MATCH (n) USING INDEX n:Awesome(prop) WHERE n:Awesome AND n.prop = 42 RETURN n"
plan.plan should equal(
NodeIndexSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), SingleQueryExpression(SignedIntegerLiteral("42")_))
NodeIndexSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")_))_))
)
}
......@@ -188,7 +188,7 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
} planFor "MATCH (n) USING INDEX n:Awesome(prop) WHERE n:Awesome AND n.prop = 42 RETURN *"
plan.plan should equal(
NodeIndexSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), SingleQueryExpression(SignedIntegerLiteral("42")_))
NodeIndexSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")_))_))
)
}
......@@ -200,8 +200,8 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
plan.plan should equal(
Selection(
List(Equals(Property(ident("n"), PropertyKeyName("prop1")_)_, SignedIntegerLiteral("42")_)_),
NodeIndexSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop2", PropertyKeyId(1)), SingleQueryExpression(SignedIntegerLiteral("3")_))
List(In(Property(ident("n"), PropertyKeyName("prop1")_)_, Collection(Seq(SignedIntegerLiteral("42")_))_)_),
NodeIndexSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop2", PropertyKeyId(1)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("3")_))_))
)
)
}
......@@ -212,7 +212,7 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
} planFor "MATCH (n) USING INDEX n:Awesome(prop) WHERE n:Awesome AND n.prop = 42 RETURN n"
plan.plan should equal(
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), SingleQueryExpression(SignedIntegerLiteral("42")_))
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop", PropertyKeyId(0)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")_))_))
)
}
......@@ -224,8 +224,8 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
plan.plan should equal(
Selection(
List(Equals(Property(ident("n"), PropertyKeyName("prop1")_)_, SignedIntegerLiteral("42")_)_),
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop2", PropertyKeyId(1)), SingleQueryExpression(SignedIntegerLiteral("3")_))
List(In(Property(ident("n"), PropertyKeyName("prop1")_)_, Collection(Seq(SignedIntegerLiteral("42")_))_)_),
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop2", PropertyKeyId(1)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("3")_))_))
)
)
}
......@@ -238,7 +238,7 @@ class LeafPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
plan.plan should equal(
Selection(
List(Equals(Property(ident("n"), PropertyKeyName("prop1")_)_, SignedIntegerLiteral("42")_)_),
List(In(Property(ident("n"), PropertyKeyName("prop1")_)_, Collection(Seq(SignedIntegerLiteral("42")_))_)_),
NodeIndexUniqueSeek("n", LabelToken("Awesome", LabelId(0)), PropertyKeyToken("prop2", PropertyKeyId(1)), ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("3")_))_))
)
)
......
......@@ -45,8 +45,8 @@ class NamedPathProjectionPlanningIntegrationTest extends CypherFunSuite with Log
Projection(
Selection(
Seq(Equals(
Identifier("a")_,
FunctionInvocation(FunctionName("head")_, FunctionInvocation(FunctionName("nodes")_, pathExpr)_)_
FunctionInvocation(FunctionName("head")_, FunctionInvocation(FunctionName("nodes")_, pathExpr)_)_,
Identifier("a")_
)_),
Expand( NodeByLabelScan("a", Left("X")), "a", Direction.OUTGOING, Seq.empty, "b", "r", SimplePatternLength )
),
......
......@@ -90,7 +90,7 @@ class PatternPredicatePlanningIntegrationTest extends CypherFunSuite with Logica
"a", Direction.OUTGOING, Seq(RelTypeName("X")_), " UNNAMED42", " UNNAMED34", SimplePatternLength
),
Ors(Set(
Equals(Property(Identifier("a")_, PropertyKeyName("prop2")_)_, SignedIntegerLiteral("9")_)_,
In(Property(Identifier("a")_, PropertyKeyName("prop2")_)_, Collection(Seq(SignedIntegerLiteral("9")_))_)_,
GreaterThan(Property(Identifier("a")_, PropertyKeyName("prop")_)_, SignedIntegerLiteral("4")_)_
))_
)
......@@ -105,7 +105,7 @@ class PatternPredicatePlanningIntegrationTest extends CypherFunSuite with Logica
SingleRow(Set("a"))(),
"a", Direction.OUTGOING, Seq(RelTypeName("X")_), " UNNAMED45", " UNNAMED37", SimplePatternLength
),
Equals(Property(Identifier("a")_, PropertyKeyName("prop")_)_, SignedIntegerLiteral("9")_)_
In(Property(Identifier("a")_, PropertyKeyName("prop")_)_, Collection(Seq(SignedIntegerLiteral("9")_))_)_
)
)
}
......@@ -121,7 +121,7 @@ class PatternPredicatePlanningIntegrationTest extends CypherFunSuite with Logica
"a", Direction.OUTGOING, Seq(RelTypeName("Y") _), " UNNAMED41", " UNNAMED33", SimplePatternLength
),
" FRESHID30",
Equals(Property(Identifier("a") _, PropertyKeyName("prop") _) _, SignedIntegerLiteral("9") _) _
In(Property(Identifier("a") _, PropertyKeyName("prop") _) _, Collection(Seq(SignedIntegerLiteral("9")_))_)_
),
Expand(
SingleRow(Set("a"))(),
......
......@@ -93,7 +93,7 @@ class WithPlanningIntegrationTest extends CypherFunSuite with LogicalPlanningTes
Map[String, Expression]("a" -> ident("a"))
),
planSelection(
Seq(Equals(Property(Identifier("r1") _, PropertyKeyName("prop") _) _, SignedIntegerLiteral("42") _) _),
Seq(In(Property(Identifier("r1") _, PropertyKeyName("prop") _) _, Collection(Seq(SignedIntegerLiteral("42")_))_)_),
planExpand(planArgumentRow(Set("a")), "a", Direction.OUTGOING, Seq(), "b", "r1", SimplePatternLength, rel)
)
),
......
......@@ -36,38 +36,7 @@ class IdSeekLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSupp
private val statistics = hardcodedStatistics
test("simple node by id seek with a node id expression") {
// given
val identifier: Identifier = Identifier("n")_
val expr = Equals(
FunctionInvocation(FunctionName("id")_, distinct = false, Array(identifier))_,
SignedIntegerLiteral("42")_
)_
val qg = QueryGraph(
selections = Selections(Set(Predicate(Set(IdName("n")), expr))),
patternNodes = Set(IdName("n"))
)
val factory = newMockedMetricsFactory
when(factory.newCardinalityEstimator(any(), any(), any())).thenReturn((plan: LogicalPlan) => plan match {
case _: NodeByIdSeek => Cardinality(1)
case _ => Cardinality(Double.MaxValue)
})
implicit val context = newMockedQueryGraphSolvingContext(
planContext = newMockedPlanContext,
query = qg,
metrics = factory.newMetrics(statistics, newMockedSemanticTable)
)
when(context.semanticTable.isNode(identifier)).thenReturn(true)
// when
val resultPlans = idSeekLeafPlanner(qg)
// then
resultPlans should equal(Candidates(
planNodeByIdSeek(IdName("n"), Seq(SignedIntegerLiteral("42")_), Seq(expr))
))
}
// NOTE: the ronja rewriters make sure that all EQUALS will be rewritten to IN so here only the latter should be tested
test("simple node by id seek with a collection of node ids") {
// given
......@@ -106,77 +75,6 @@ class IdSeekLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSupp
))
}
test("simple directed relationship by id seek with a rel id expression") {
// given
val rIdent: Identifier = Identifier("r")_
val expr = Equals(
FunctionInvocation(FunctionName("id")_, distinct = false, Array(rIdent))_,
SignedIntegerLiteral("42")_
)_
val from = IdName("from")
val end = IdName("to")
val patternRel = PatternRelationship(IdName("r"), (from, end), Direction.OUTGOING, Seq.empty, SimplePatternLength)
val qg = QueryGraph(
selections = Selections(Set(Predicate(Set(IdName("r")), expr))),
patternNodes = Set(from, end),
patternRelationships = Set(patternRel)
)
val factory = newMockedMetricsFactory
when(factory.newCardinalityEstimator(any(), any(), any())).thenReturn((plan: LogicalPlan) => plan match {
case _: DirectedRelationshipByIdSeek => Cardinality(1)
case _ => Cardinality(Double.MaxValue)
})
implicit val context = newMockedQueryGraphSolvingContext(
planContext = newMockedPlanContext,
query = qg,
metrics = factory.newMetrics(statistics, newMockedSemanticTable)
)
when(context.semanticTable.isRelationship(rIdent)).thenReturn(true)
// when
val resultPlans = idSeekLeafPlanner(qg)
// then
resultPlans should equal(Candidates(planDirectedRelationshipByIdSeek(IdName("r"), Seq(SignedIntegerLiteral("42")_), from, end, patternRel, Seq(expr))))
}
test("simple undirected relationship by id seek with a rel id expression") {
// given
val rIdent: Identifier = Identifier("r")_
val expr = Equals(
FunctionInvocation(FunctionName("id")_, distinct = false, Array(rIdent))_,
SignedIntegerLiteral("42")_
)_
val from = IdName("from")
val end = IdName("to")
val patternRel = PatternRelationship(IdName("r"), (from, end), Direction.BOTH, Seq.empty, SimplePatternLength)
val qg = QueryGraph(
selections = Selections(Set(Predicate(Set(IdName("r")), expr))),
patternNodes = Set(from, end),
patternRelationships = Set(patternRel)
)
val factory = newMockedMetricsFactory
when(factory.newCardinalityEstimator(any(), any(), any())).thenReturn((plan: LogicalPlan) => plan match {
case _: UndirectedRelationshipByIdSeek => Cardinality(2)
case _ => Cardinality(Double.MaxValue)
})
implicit val context = newMockedQueryGraphSolvingContext(
planContext = newMockedPlanContext,
query = qg,
metrics = factory.newMetrics(statistics, newMockedSemanticTable)
)
when(context.semanticTable.isRelationship(rIdent)).thenReturn(true)
// when
val resultPlans = idSeekLeafPlanner(qg)
// then
resultPlans should equal(Candidates(planUndirectedRelationshipByIdSeek(IdName("r"), Seq(SignedIntegerLiteral("42")_), from, end, patternRel, Seq(expr))))
}
test("simple directed relationship by id seek with a collection of relationship ids") {
// given
val rIdent: Identifier = Identifier("r")_
......@@ -254,12 +152,12 @@ class IdSeekLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSupp
), from, end, patternRel, Seq(expr))))
}
test("simple undirected typed relationship by id seek with a rel id expression") {
test("simple undirected typed relationship by id seek with a collection of relationship ids") {
// given
val rIdent: Identifier = Identifier("r")_
val expr = Equals(
val expr = In(
FunctionInvocation(FunctionName("id")_, distinct = false, Array(rIdent))_,
SignedIntegerLiteral("42")_
Collection(Seq(SignedIntegerLiteral("42")_))_
)_
val from = IdName("from")
val end = IdName("to")
......@@ -301,12 +199,12 @@ class IdSeekLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSupp
))
}
test("simple undirected multi-typed relationship by id seek with a rel id expression") {
test("simple undirected multi-typed relationship by id seek with a collection of relationship ids") {
// given
val rIdent: Identifier = Identifier("r")_
val expr = Equals(
val expr = In(
FunctionInvocation(FunctionName("id")_, distinct = false, Array(rIdent))_,
SignedIntegerLiteral("42")_
Collection(Seq(SignedIntegerLiteral("42")_))_
)_
val from = IdName("from")
val end = IdName("to")
......
......@@ -25,7 +25,7 @@ import org.neo4j.cypher.internal.compiler.v2_1.ast._
import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.steps.{uniqueIndexSeekLeafPlanner, indexSeekLeafPlanner}
import org.neo4j.cypher.internal.compiler.v2_1.planner.logical.QueryGraphSolvingContext
import org.neo4j.cypher.internal.compiler.v2_1.planner.BeLikeMatcher._
import org.neo4j.cypher.internal.compiler.v2_1.commands.{ManyQueryExpression, SingleQueryExpression}
import org.neo4j.cypher.internal.compiler.v2_1.commands.ManyQueryExpression
class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSupport2 {
......@@ -35,14 +35,11 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
val lit42 = SignedIntegerLiteral("42") _
val lit6 = SignedIntegerLiteral("6") _
val equalsValue = Equals(
property ,
lit42
) _
val inCollectionValue = In(property, Collection(Seq(lit42))_)_
test("does not plan index seek when no index exist") {
new given {
qg = queryGraph(equalsValue, hasLabels)
qg = queryGraph(inCollectionValue, hasLabels)
withQueryGraphSolvingContext { (ctx: QueryGraphSolvingContext) =>
// when
......@@ -55,7 +52,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
}
test("does not plan index seek when no unique index exist") {
new given {
qg = queryGraph(equalsValue, hasLabels)
qg = queryGraph(inCollectionValue, hasLabels)
withQueryGraphSolvingContext { (ctx: QueryGraphSolvingContext) =>
// when
......@@ -69,7 +66,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
test("index scan when there is an index on the property") {
new given {
qg = queryGraph(equalsValue, hasLabels)
qg = queryGraph(inCollectionValue, hasLabels)
indexOn("Awesome", "prop")
......@@ -79,7 +76,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
// then
resultPlans.plans.map(_.plan) should beLike {
case Seq(NodeIndexSeek(`idName`, _, _, SingleQueryExpression(SignedIntegerLiteral("42")))) => ()
case Seq(NodeIndexSeek(`idName`, _, _, ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")))))) => ()
}
}
}
......@@ -105,7 +102,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
test("unique index scan when there is an unique index on the property") {
new given {
qg = queryGraph(equalsValue, hasLabels)
qg = queryGraph(inCollectionValue, hasLabels)
uniqueIndexOn("Awesome", "prop")
......@@ -115,7 +112,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
// then
resultPlans.plans.map(_.plan) should beLike {
case Seq(NodeIndexUniqueSeek(`idName`, _, _, SingleQueryExpression(SignedIntegerLiteral("42")))) => ()
case Seq(NodeIndexUniqueSeek(`idName`, _, _, ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")))))) => ()
}
}
}
......@@ -125,7 +122,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
val hint: UsingIndexHint = UsingIndexHint(ident("n"), LabelName("Awesome")_, ident("prop"))_
new given {
qg = queryGraph(equalsValue, hasLabels).addHints(Some(hint))
qg = queryGraph(inCollectionValue, hasLabels).addHints(Some(hint))
indexOn("Awesome", "prop")
......@@ -135,7 +132,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
// then
resultPlans.plans.map(_.plan) should beLike {
case Seq(NodeIndexSeek(`idName`, _, _, SingleQueryExpression(SignedIntegerLiteral("42")))) => ()
case Seq(NodeIndexSeek(`idName`, _, _, ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")))))) => ()
}
resultPlans.plans.map(_.solved.graph) should beLike {
......@@ -149,7 +146,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
val hint: UsingIndexHint = UsingIndexHint(ident("n"), LabelName("Awesome")_, ident("prop"))_
new given {
qg = queryGraph(equalsValue, hasLabels).addHints(Some(hint))
qg = queryGraph(inCollectionValue, hasLabels).addHints(Some(hint))
uniqueIndexOn("Awesome", "prop")
......@@ -159,7 +156,7 @@ class IndexLeafPlannerTest extends CypherFunSuite with LogicalPlanningTestSuppor
// then
resultPlans.plans.map(_.plan) should beLike {
case Seq(NodeIndexUniqueSeek(`idName`, _, _, SingleQueryExpression(SignedIntegerLiteral("42")))) => ()
case Seq(NodeIndexUniqueSeek(`idName`, _, _, ManyQueryExpression(Collection(Seq(SignedIntegerLiteral("42")))))) => ()
}
resultPlans.plans.map(_.solved.graph) should beLike {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment