Commit 402a6dd9 authored by fickludd's avatar fickludd Committed by Johan Teleman
Browse files

Fix bug with slot allocation of foreach with missing type information

Showing with 22 additions and 9 deletions
+22 -9
......@@ -51,8 +51,7 @@ class SemanticTable(
throw new InternalException(s"Did not find any type information for variable $s", e)
}
def getActualTypeFor(expr: Expression): TypeSpec =
types.getOrElse(expr, throw new InternalException(s"Did not find any type information for expression $expr")).actual
def getActualTypeFor(expr: Expression): Option[TypeSpec] = types.get(expr).map(_.actual)
def containsNode(expr: String): Boolean = types.exists {
case (v@Variable(name), _) => name == expr && isNode(v) // NOTE: Profiling showed that checking node type last is better
......
......@@ -201,4 +201,18 @@ class ForeachAcceptanceTest extends ExecutionEngineFunSuite with CypherCompariso
TestConfiguration(Versions(Versions.V3_1, Versions.V3_3), Planners.Cost, Runtimes.Default)
failWithError(config, query, List("Expected to find a node at"))
}
test("should FOREACH over nodes in path") {
val a = createNode()
val b = createNode()
relate(a, b)
val query =
"""MATCH p = ()-->()
|FOREACH (n IN nodes(p) | SET n.marked = true)""".stripMargin
val result = executeWith(Configs.Interpreted - Configs.Cost2_3, query)
assertStats(result, propertiesWritten = 2)
}
}
......@@ -58,7 +58,7 @@ object SlotAllocation {
argumentSizes: ArgumentSizes)
/**
* Allocate slot for every operator in the logical plan tree {@code lp}.
* Allocate slot for every operator in the logical plan tree `lp`.
*
* @param lp the logical plan to process.
* @return the slot configurations of every operator.
......@@ -245,7 +245,7 @@ object SlotAllocation {
}
/**
* Compute the slot configuration of a leaf logical plan operator {@code lp}.
* Compute the slot configuration of a leaf logical plan operator `lp`.
*
* @param lp the operator to compute slots for.
* @param nullable true if new slots are nullable
......@@ -290,7 +290,7 @@ object SlotAllocation {
}
/**
* Compute the slot configuration of a single source logical plan operator {@code lp}.
* Compute the slot configuration of a single source logical plan operator `lp`.
*
* @param lp the operator to compute slots for.
* @param nullable true if new slots are nullable
......@@ -502,7 +502,7 @@ object SlotAllocation {
}
/**
* Compute the slot configuration of a branching logical plan operator {@code lp}.
* Compute the slot configuration of a branching logical plan operator `lp`.
*
* @param lp the operator to compute slots for.
* @param nullable true if new slots are nullable
......@@ -655,9 +655,9 @@ object SlotAllocation {
case ForeachApply(_, _, variableName, listExpression) =>
// The slot for the iteration variable of foreach needs to be available as an argument on the rhs of the apply
// so we allocate it on the lhs (even though its value will not be needed after the foreach is done)
val typeSpec = semanticTable.getActualTypeFor(listExpression)
val listOfNodes = typeSpec.contains(ListType(CTNode))
val listOfRels = typeSpec.contains(ListType(CTRelationship))
val maybeTypeSpec = semanticTable.getActualTypeFor(listExpression)
val listOfNodes = maybeTypeSpec.exists(_.contains(ListType(CTNode)))
val listOfRels = maybeTypeSpec.exists(_.contains(ListType(CTRelationship)))
(listOfNodes, listOfRels) match {
case (true, false) => lhs.newLong(variableName, true, CTNode)
......
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