Correctly check variables inside property maps
Reviewers: florijan, mislav.bradac Reviewed By: mislav.bradac Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D271
This commit is contained in:
parent
55ef48c78e
commit
596b015e99
@ -73,12 +73,10 @@ void SymbolGenerator::PostVisit(With &with) {
|
|||||||
|
|
||||||
void SymbolGenerator::Visit(Identifier &ident) {
|
void SymbolGenerator::Visit(Identifier &ident) {
|
||||||
Symbol symbol;
|
Symbol symbol;
|
||||||
if (scope_.in_pattern) {
|
if (scope_.in_pattern && !scope_.in_property_map) {
|
||||||
// Patterns can bind new symbols or reference already bound. But there
|
// Patterns can bind new symbols or reference already bound. But there
|
||||||
// are the following special cases:
|
// are the following special cases:
|
||||||
// 1) Expressions in property maps `{prop_name: expr}` can only reference
|
// 1) Patterns used to create nodes and edges cannot redeclare already
|
||||||
// bound variables.
|
|
||||||
// 2) Patterns used to create nodes and edges cannot redeclare already
|
|
||||||
// established bindings. Declaration only happens in single node
|
// established bindings. Declaration only happens in single node
|
||||||
// patterns and in edge patterns. OpenCypher example,
|
// patterns and in edge patterns. OpenCypher example,
|
||||||
// `MATCH (n) CREATE (n)` should throw an error that `n` is already
|
// `MATCH (n) CREATE (n)` should throw an error that `n` is already
|
||||||
@ -87,12 +85,9 @@ void SymbolGenerator::Visit(Identifier &ident) {
|
|||||||
// Additionally, we will support edge referencing in pattern:
|
// Additionally, we will support edge referencing in pattern:
|
||||||
// `MATCH (n) - [r] -> (n) - [r] -> (n) RETURN r`, which would
|
// `MATCH (n) - [r] -> (n) - [r] -> (n) RETURN r`, which would
|
||||||
// usually raise redeclaration of `r`.
|
// usually raise redeclaration of `r`.
|
||||||
if (scope_.in_property_map && !HasSymbol(ident.name_)) {
|
if ((scope_.in_create_node || scope_.in_create_edge) &&
|
||||||
// Case 1)
|
|
||||||
throw UnboundVariableError(ident.name_);
|
|
||||||
} else if ((scope_.in_create_node || scope_.in_create_edge) &&
|
|
||||||
HasSymbol(ident.name_)) {
|
HasSymbol(ident.name_)) {
|
||||||
// Case 2)
|
// Case 1)
|
||||||
throw RedeclareVariableError(ident.name_);
|
throw RedeclareVariableError(ident.name_);
|
||||||
}
|
}
|
||||||
auto type = Symbol::Type::Vertex;
|
auto type = Symbol::Type::Vertex;
|
||||||
|
@ -447,4 +447,25 @@ TEST(TestSymbolGenerator, NestedAggregation) {
|
|||||||
EXPECT_THROW(query->Accept(symbol_generator), SemanticException);
|
EXPECT_THROW(query->Accept(symbol_generator), SemanticException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestSymbolGenerator, MatchPropCreateNodeProp) {
|
||||||
|
// Test MATCH (n) CREATE (m {prop: n.prop})
|
||||||
|
Dbms dbms;
|
||||||
|
auto dba = dbms.active();
|
||||||
|
auto prop = dba->property("prop");
|
||||||
|
AstTreeStorage storage;
|
||||||
|
auto node_n = NODE("n");
|
||||||
|
auto node_m = NODE("m");
|
||||||
|
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||||
|
node_m->properties_[prop] = n_prop;
|
||||||
|
auto query = QUERY(MATCH(PATTERN(node_n)), CREATE(PATTERN(node_m)));
|
||||||
|
SymbolTable symbol_table;
|
||||||
|
SymbolGenerator symbol_generator(symbol_table);
|
||||||
|
query->Accept(symbol_generator);
|
||||||
|
EXPECT_EQ(symbol_table.max_position(), 2);
|
||||||
|
auto n = symbol_table.at(*node_n->identifier_);
|
||||||
|
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
|
||||||
|
auto m = symbol_table.at(*node_m->identifier_);
|
||||||
|
EXPECT_NE(n, m);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user