2023-03-07 07:28:41 +08:00
|
|
|
// Copyright 2023 Memgraph Ltd.
|
2021-10-26 14:53:56 +08:00
|
|
|
//
|
|
|
|
// Use of this software is governed by the Business Source License
|
|
|
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
|
|
// License, and you may not use this file except in compliance with the Business Source License.
|
|
|
|
//
|
|
|
|
// As of the Change Date specified in that file, in accordance with
|
|
|
|
// the Business Source License, use of this software will be governed
|
|
|
|
// by the Apache License, Version 2.0, included in the file
|
|
|
|
// licenses/APL.txt.
|
|
|
|
|
2017-04-24 19:51:16 +08:00
|
|
|
/// @file
|
|
|
|
/// This file provides macros for easier construction of openCypher query AST.
|
|
|
|
/// The usage of macros is very similar to how one would write openCypher. For
|
|
|
|
/// example:
|
|
|
|
///
|
2018-05-22 22:45:52 +08:00
|
|
|
/// AstStorage storage; // Macros rely on storage being in scope.
|
2018-06-19 19:52:11 +08:00
|
|
|
/// // PROPERTY_LOOKUP and PROPERTY_PAIR macros
|
2018-07-26 15:08:21 +08:00
|
|
|
/// // rely on a DbAccessor *reference* named dba.
|
2018-10-09 17:09:10 +08:00
|
|
|
/// database::GraphDb db;
|
2018-07-26 15:08:21 +08:00
|
|
|
/// auto dba_ptr = db.Access();
|
|
|
|
/// auto &dba = *dba_ptr;
|
2017-04-24 19:51:16 +08:00
|
|
|
///
|
|
|
|
/// QUERY(MATCH(PATTERN(NODE("n"), EDGE("e"), NODE("m"))),
|
|
|
|
/// WHERE(LESS(PROPERTY_LOOKUP("e", edge_prop), LITERAL(3))),
|
|
|
|
/// RETURN(SUM(PROPERTY_LOOKUP("m", prop)), AS("sum"),
|
|
|
|
/// ORDER_BY(IDENT("sum")),
|
|
|
|
/// SKIP(ADD(LITERAL(1), LITERAL(2)))));
|
|
|
|
///
|
|
|
|
/// Each of the macros is accompanied by a function. The functions use overload
|
|
|
|
/// resolution and template magic to provide a type safe way of constructing
|
|
|
|
/// queries. Although the functions can be used by themselves, it is more
|
|
|
|
/// convenient to use the macros.
|
|
|
|
|
2017-05-30 21:19:38 +08:00
|
|
|
#pragma once
|
|
|
|
|
2017-09-18 20:40:36 +08:00
|
|
|
#include <map>
|
2018-11-07 17:54:35 +08:00
|
|
|
#include <sstream>
|
2017-09-18 20:40:36 +08:00
|
|
|
#include <string>
|
2017-10-02 16:34:38 +08:00
|
|
|
#include <unordered_map>
|
2017-04-24 19:51:16 +08:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
2017-04-24 22:01:00 +08:00
|
|
|
#include "query/frontend/ast/ast.hpp"
|
2018-11-07 17:54:35 +08:00
|
|
|
#include "query/frontend/ast/pretty_print.hpp"
|
2019-11-22 00:24:01 +08:00
|
|
|
#include "storage/v2/id_types.hpp"
|
2019-11-22 01:38:01 +08:00
|
|
|
#include "utils/string.hpp"
|
2019-11-22 00:24:01 +08:00
|
|
|
|
2022-02-22 20:33:45 +08:00
|
|
|
namespace memgraph::query {
|
2017-03-24 23:50:42 +08:00
|
|
|
|
|
|
|
namespace test_common {
|
|
|
|
|
2019-08-22 20:50:57 +08:00
|
|
|
auto ToIntList(const TypedValue &t) {
|
|
|
|
std::vector<int64_t> list;
|
2019-05-21 22:06:05 +08:00
|
|
|
for (auto x : t.ValueList()) {
|
2019-08-22 20:50:57 +08:00
|
|
|
list.push_back(x.ValueInt());
|
2017-05-19 21:49:25 +08:00
|
|
|
}
|
|
|
|
return list;
|
|
|
|
};
|
|
|
|
|
2019-08-22 20:50:57 +08:00
|
|
|
auto ToIntMap(const TypedValue &t) {
|
|
|
|
std::map<std::string, int64_t> map;
|
2021-02-18 22:32:43 +08:00
|
|
|
for (const auto &kv : t.ValueMap()) map.emplace(kv.first, kv.second.ValueInt());
|
Collect Map added
Summary:
Tests are on the way. Please first comment if you're OK with this implementation, some points are discussable.
What works now:
```
bash:MEMGRAPH_ROOT/build/>./tests/manual/console 10
MG>MATCH (n) RETURN COLLECT("age_" + n.age, n.height)
+-----------------------------------------------------------------------------------------------------------------------------------+
| COLLECT("age_" + n.age, n.height) |
+-----------------------------------------------------------------------------------------------------------------------------------+
| {age_10: 176, age_13: 180, age_24: 172, age_25: 179, age_32: 123, age_33: 186, age_37: 147, age_43: 162, age_49: 126, age_6: 170} |
+-----------------------------------------------------------------------------------------------------------------------------------+
```
Reviewers: mislav.bradac, teon.banek, buda
Reviewed By: mislav.bradac, buda
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D695
2017-08-23 16:43:45 +08:00
|
|
|
return map;
|
|
|
|
};
|
|
|
|
|
2019-01-16 17:43:32 +08:00
|
|
|
std::string ToString(Expression *expr) {
|
2018-11-07 17:54:35 +08:00
|
|
|
std::ostringstream ss;
|
2019-01-16 17:43:32 +08:00
|
|
|
PrintExpression(expr, &ss);
|
2018-11-07 17:54:35 +08:00
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2019-01-16 17:43:32 +08:00
|
|
|
std::string ToString(NamedExpression *expr) {
|
2018-11-07 17:54:35 +08:00
|
|
|
std::ostringstream ss;
|
2019-01-16 17:43:32 +08:00
|
|
|
PrintExpression(expr, &ss);
|
2018-11-07 17:54:35 +08:00
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2017-04-26 19:49:41 +08:00
|
|
|
// Custom types for ORDER BY, SKIP, LIMIT, ON MATCH and ON CREATE expressions,
|
|
|
|
// so that they can be used to resolve function calls.
|
2017-04-24 19:51:16 +08:00
|
|
|
struct OrderBy {
|
2018-10-04 17:57:23 +08:00
|
|
|
std::vector<SortItem> expressions;
|
2017-04-24 19:51:16 +08:00
|
|
|
};
|
2017-04-20 17:20:20 +08:00
|
|
|
struct Skip {
|
2017-04-24 19:51:16 +08:00
|
|
|
Expression *expression = nullptr;
|
2017-04-20 17:20:20 +08:00
|
|
|
};
|
|
|
|
struct Limit {
|
2017-04-24 19:51:16 +08:00
|
|
|
Expression *expression = nullptr;
|
2017-04-20 17:20:20 +08:00
|
|
|
};
|
2017-04-26 19:49:41 +08:00
|
|
|
struct OnMatch {
|
|
|
|
std::vector<Clause *> set;
|
|
|
|
};
|
|
|
|
struct OnCreate {
|
|
|
|
std::vector<Clause *> set;
|
|
|
|
};
|
2017-04-20 17:20:20 +08:00
|
|
|
|
2017-04-24 19:51:16 +08:00
|
|
|
// Helper functions for filling the OrderBy with expressions.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto FillOrderBy(OrderBy &order_by, Expression *expression, Ordering ordering = Ordering::ASC) {
|
2018-10-04 17:57:23 +08:00
|
|
|
order_by.expressions.push_back({ordering, expression});
|
2017-04-24 19:51:16 +08:00
|
|
|
}
|
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto FillOrderBy(OrderBy &order_by, Expression *expression, Ordering ordering, T... rest) {
|
2017-04-24 19:51:16 +08:00
|
|
|
FillOrderBy(order_by, expression, ordering);
|
|
|
|
FillOrderBy(order_by, rest...);
|
|
|
|
}
|
|
|
|
template <class... T>
|
|
|
|
auto FillOrderBy(OrderBy &order_by, Expression *expression, T... rest) {
|
|
|
|
FillOrderBy(order_by, expression);
|
|
|
|
FillOrderBy(order_by, rest...);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create OrderBy expressions.
|
|
|
|
///
|
|
|
|
/// The supported combination of arguments is: (Expression, [Ordering])+
|
|
|
|
/// Since the Ordering is optional, by default it is ascending.
|
|
|
|
template <class... T>
|
|
|
|
auto GetOrderBy(T... exprs) {
|
|
|
|
OrderBy order_by;
|
|
|
|
FillOrderBy(order_by, exprs...);
|
|
|
|
return order_by;
|
|
|
|
}
|
|
|
|
|
2017-03-24 23:50:42 +08:00
|
|
|
/// Create PropertyLookup with given name and property.
|
|
|
|
///
|
|
|
|
/// Name is used to create the Identifier which is used for property lookup.
|
2019-11-22 00:24:01 +08:00
|
|
|
template <class TDbAccessor>
|
2022-02-22 20:33:45 +08:00
|
|
|
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba, const std::string &name,
|
|
|
|
memgraph::storage::PropertyId property) {
|
2021-02-18 22:32:43 +08:00
|
|
|
return storage.Create<PropertyLookup>(storage.Create<Identifier>(name),
|
|
|
|
storage.GetPropertyIx(dba.PropertyToName(property)));
|
2019-11-22 00:24:01 +08:00
|
|
|
}
|
2018-06-19 19:52:11 +08:00
|
|
|
|
2019-11-22 00:24:01 +08:00
|
|
|
template <class TDbAccessor>
|
2022-02-22 20:33:45 +08:00
|
|
|
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba, Expression *expr,
|
|
|
|
memgraph::storage::PropertyId property) {
|
2021-02-18 22:32:43 +08:00
|
|
|
return storage.Create<PropertyLookup>(expr, storage.GetPropertyIx(dba.PropertyToName(property)));
|
2019-11-22 00:24:01 +08:00
|
|
|
}
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
|
|
|
|
template <class TDbAccessor>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba, Expression *expr, const std::string &property) {
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
return storage.Create<PropertyLookup>(expr, storage.GetPropertyIx(property));
|
2017-08-08 19:43:42 +08:00
|
|
|
}
|
2018-06-19 19:52:11 +08:00
|
|
|
|
|
|
|
template <class TDbAccessor>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &, const std::string &name,
|
2022-02-22 20:33:45 +08:00
|
|
|
const std::pair<std::string, memgraph::storage::PropertyId> &prop_pair) {
|
2021-02-18 22:32:43 +08:00
|
|
|
return storage.Create<PropertyLookup>(storage.Create<Identifier>(name), storage.GetPropertyIx(prop_pair.first));
|
2017-08-08 19:43:42 +08:00
|
|
|
}
|
2018-06-19 19:52:11 +08:00
|
|
|
|
|
|
|
template <class TDbAccessor>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &, Expression *expr,
|
2022-02-22 20:33:45 +08:00
|
|
|
const std::pair<std::string, memgraph::storage::PropertyId> &prop_pair) {
|
2021-02-18 22:32:43 +08:00
|
|
|
return storage.Create<PropertyLookup>(expr, storage.GetPropertyIx(prop_pair.first));
|
2017-05-05 21:34:07 +08:00
|
|
|
}
|
2017-03-24 23:50:42 +08:00
|
|
|
|
2023-05-17 02:05:35 +08:00
|
|
|
/// Create an AllPropertiesLookup from the given name.
|
|
|
|
auto GetAllPropertiesLookup(AstStorage &storage, const std::string &name) {
|
|
|
|
return storage.Create<AllPropertiesLookup>(storage.Create<Identifier>(name));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create an AllPropertiesLookup from the given expression.
|
|
|
|
auto GetAllPropertiesLookup(AstStorage &storage, Expression *expr) { return storage.Create<AllPropertiesLookup>(expr); }
|
|
|
|
|
2017-10-05 17:25:52 +08:00
|
|
|
/// Create an EdgeAtom with given name, direction and edge_type.
|
2017-03-24 23:50:42 +08:00
|
|
|
///
|
|
|
|
/// Name is used to create the Identifier which is assigned to the edge.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetEdge(AstStorage &storage, const std::string &name, EdgeAtom::Direction dir = EdgeAtom::Direction::BOTH,
|
2023-03-07 07:28:41 +08:00
|
|
|
const std::vector<std::string> &edge_types = {}, const bool user_declared = true) {
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
std::vector<EdgeTypeIx> types;
|
|
|
|
types.reserve(edge_types.size());
|
|
|
|
for (const auto &type : edge_types) {
|
|
|
|
types.push_back(storage.GetEdgeTypeIx(type));
|
|
|
|
}
|
2023-03-07 07:28:41 +08:00
|
|
|
return storage.Create<EdgeAtom>(storage.Create<Identifier>(name, user_declared), EdgeAtom::Type::SINGLE, dir, types);
|
2017-10-05 17:25:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a variable length expansion EdgeAtom with given name, direction and
|
|
|
|
/// edge_type.
|
2017-03-24 23:50:42 +08:00
|
|
|
///
|
2017-10-05 17:25:52 +08:00
|
|
|
/// Name is used to create the Identifier which is assigned to the edge.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetEdgeVariable(AstStorage &storage, const std::string &name, EdgeAtom::Type type = EdgeAtom::Type::DEPTH_FIRST,
|
2017-10-05 17:25:52 +08:00
|
|
|
EdgeAtom::Direction dir = EdgeAtom::Direction::BOTH,
|
2021-02-18 22:32:43 +08:00
|
|
|
const std::vector<std::string> &edge_types = {}, Identifier *flambda_inner_edge = nullptr,
|
|
|
|
Identifier *flambda_inner_node = nullptr, Identifier *wlambda_inner_edge = nullptr,
|
|
|
|
Identifier *wlambda_inner_node = nullptr, Expression *wlambda_expression = nullptr,
|
2018-10-18 17:16:32 +08:00
|
|
|
Identifier *total_weight = nullptr) {
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
std::vector<EdgeTypeIx> types;
|
|
|
|
types.reserve(edge_types.size());
|
|
|
|
for (const auto &type : edge_types) {
|
|
|
|
types.push_back(storage.GetEdgeTypeIx(type));
|
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
auto r_val = storage.Create<EdgeAtom>(storage.Create<Identifier>(name), type, dir, types);
|
2018-10-18 17:16:32 +08:00
|
|
|
|
2018-02-08 19:57:12 +08:00
|
|
|
r_val->filter_lambda_.inner_edge =
|
2022-02-22 20:33:45 +08:00
|
|
|
flambda_inner_edge ? flambda_inner_edge : storage.Create<Identifier>(memgraph::utils::RandomString(20));
|
2018-02-08 19:57:12 +08:00
|
|
|
r_val->filter_lambda_.inner_node =
|
2022-02-22 20:33:45 +08:00
|
|
|
flambda_inner_node ? flambda_inner_node : storage.Create<Identifier>(memgraph::utils::RandomString(20));
|
2018-10-18 17:16:32 +08:00
|
|
|
|
|
|
|
if (type == EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) {
|
|
|
|
r_val->weight_lambda_.inner_edge =
|
2022-02-22 20:33:45 +08:00
|
|
|
wlambda_inner_edge ? wlambda_inner_edge : storage.Create<Identifier>(memgraph::utils::RandomString(20));
|
2018-10-18 17:16:32 +08:00
|
|
|
r_val->weight_lambda_.inner_node =
|
2022-02-22 20:33:45 +08:00
|
|
|
wlambda_inner_node ? wlambda_inner_node : storage.Create<Identifier>(memgraph::utils::RandomString(20));
|
2018-10-18 17:16:32 +08:00
|
|
|
r_val->weight_lambda_.expression =
|
2022-02-22 20:33:45 +08:00
|
|
|
wlambda_expression ? wlambda_expression : storage.Create<memgraph::query::PrimitiveLiteral>(1);
|
2018-10-18 17:16:32 +08:00
|
|
|
|
|
|
|
r_val->total_weight_ = total_weight;
|
|
|
|
}
|
|
|
|
|
2017-10-05 17:25:52 +08:00
|
|
|
return r_val;
|
2017-03-24 23:50:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a NodeAtom with given name and label.
|
|
|
|
///
|
|
|
|
/// Name is used to create the Identifier which is assigned to the node.
|
2023-03-07 07:28:41 +08:00
|
|
|
auto GetNode(AstStorage &storage, const std::string &name, std::optional<std::string> label = std::nullopt,
|
|
|
|
const bool user_declared = true) {
|
|
|
|
auto node = storage.Create<NodeAtom>(storage.Create<Identifier>(name, user_declared));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
if (label) node->labels_.emplace_back(storage.GetLabelIx(*label));
|
2017-03-24 23:50:42 +08:00
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a Pattern with given atoms.
|
2018-05-22 22:45:52 +08:00
|
|
|
auto GetPattern(AstStorage &storage, std::vector<PatternAtom *> atoms) {
|
2017-03-24 23:50:42 +08:00
|
|
|
auto pattern = storage.Create<Pattern>();
|
2022-02-22 20:33:45 +08:00
|
|
|
pattern->identifier_ = storage.Create<Identifier>(memgraph::utils::RandomString(20), false);
|
2017-09-18 20:40:36 +08:00
|
|
|
pattern->atoms_.insert(pattern->atoms_.begin(), atoms.begin(), atoms.end());
|
|
|
|
return pattern;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a Pattern with given name and atoms.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetPattern(AstStorage &storage, const std::string &name, std::vector<PatternAtom *> atoms) {
|
2017-09-18 20:40:36 +08:00
|
|
|
auto pattern = storage.Create<Pattern>();
|
|
|
|
pattern->identifier_ = storage.Create<Identifier>(name, true);
|
2017-03-24 23:50:42 +08:00
|
|
|
pattern->atoms_.insert(pattern->atoms_.begin(), atoms.begin(), atoms.end());
|
|
|
|
return pattern;
|
|
|
|
}
|
|
|
|
|
2017-04-28 16:37:49 +08:00
|
|
|
/// This function fills an AST node which with given patterns.
|
2017-03-24 23:50:42 +08:00
|
|
|
///
|
|
|
|
/// The function is most commonly used to create Match and Create clauses.
|
|
|
|
template <class TWithPatterns>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetWithPatterns(TWithPatterns *with_patterns, std::vector<Pattern *> patterns) {
|
|
|
|
with_patterns->patterns_.insert(with_patterns->patterns_.begin(), patterns.begin(), patterns.end());
|
2017-03-24 23:50:42 +08:00
|
|
|
return with_patterns;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a query with given clauses.
|
2017-11-29 20:55:02 +08:00
|
|
|
|
|
|
|
auto GetSingleQuery(SingleQuery *single_query, Clause *clause) {
|
|
|
|
single_query->clauses_.emplace_back(clause);
|
|
|
|
return single_query;
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
}
|
2017-11-29 20:55:02 +08:00
|
|
|
auto GetSingleQuery(SingleQuery *single_query, Match *match, Where *where) {
|
2017-04-05 20:19:14 +08:00
|
|
|
match->where_ = where;
|
2017-11-29 20:55:02 +08:00
|
|
|
single_query->clauses_.emplace_back(match);
|
|
|
|
return single_query;
|
2017-04-05 20:19:14 +08:00
|
|
|
}
|
2017-11-29 20:55:02 +08:00
|
|
|
auto GetSingleQuery(SingleQuery *single_query, With *with, Where *where) {
|
2017-04-05 20:19:14 +08:00
|
|
|
with->where_ = where;
|
2017-11-29 20:55:02 +08:00
|
|
|
single_query->clauses_.emplace_back(with);
|
|
|
|
return single_query;
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
}
|
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetSingleQuery(SingleQuery *single_query, Match *match, Where *where, T *...clauses) {
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
match->where_ = where;
|
2017-11-29 20:55:02 +08:00
|
|
|
single_query->clauses_.emplace_back(match);
|
|
|
|
return GetSingleQuery(single_query, clauses...);
|
2017-03-24 23:50:42 +08:00
|
|
|
}
|
2017-04-05 20:19:14 +08:00
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetSingleQuery(SingleQuery *single_query, With *with, Where *where, T *...clauses) {
|
2017-04-05 20:19:14 +08:00
|
|
|
with->where_ = where;
|
2017-11-29 20:55:02 +08:00
|
|
|
single_query->clauses_.emplace_back(with);
|
|
|
|
return GetSingleQuery(single_query, clauses...);
|
2017-04-05 20:19:14 +08:00
|
|
|
}
|
2017-11-29 20:55:02 +08:00
|
|
|
|
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetSingleQuery(SingleQuery *single_query, Clause *clause, T *...clauses) {
|
2017-11-29 20:55:02 +08:00
|
|
|
single_query->clauses_.emplace_back(clause);
|
|
|
|
return GetSingleQuery(single_query, clauses...);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto GetCypherUnion(CypherUnion *cypher_union, SingleQuery *single_query) {
|
|
|
|
cypher_union->single_query_ = single_query;
|
|
|
|
return cypher_union;
|
|
|
|
}
|
|
|
|
|
2018-05-22 22:45:52 +08:00
|
|
|
auto GetQuery(AstStorage &storage, SingleQuery *single_query) {
|
2018-10-19 22:18:44 +08:00
|
|
|
auto *query = storage.Create<CypherQuery>();
|
2018-10-10 21:19:34 +08:00
|
|
|
query->single_query_ = single_query;
|
|
|
|
return query;
|
2017-11-29 20:55:02 +08:00
|
|
|
}
|
|
|
|
|
2017-04-05 20:19:14 +08:00
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetQuery(AstStorage &storage, SingleQuery *single_query, T *...cypher_unions) {
|
2018-10-19 22:18:44 +08:00
|
|
|
auto *query = storage.Create<CypherQuery>();
|
2018-10-10 21:19:34 +08:00
|
|
|
query->single_query_ = single_query;
|
|
|
|
query->cypher_unions_ = std::vector<CypherUnion *>{cypher_unions...};
|
|
|
|
return query;
|
2017-04-05 20:19:14 +08:00
|
|
|
}
|
2017-03-24 23:50:42 +08:00
|
|
|
|
2017-04-24 19:51:16 +08:00
|
|
|
// Helper functions for constructing RETURN and WITH clauses.
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &, ReturnBody &body, NamedExpression *named_expr) {
|
2017-05-31 20:00:30 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &storage, ReturnBody &body, const std::string &name) {
|
2018-10-18 17:16:32 +08:00
|
|
|
if (name == "*") {
|
|
|
|
body.all_identifiers = true;
|
|
|
|
} else {
|
2022-02-22 20:33:45 +08:00
|
|
|
auto *ident = storage.Create<memgraph::query::Identifier>(name);
|
|
|
|
auto *named_expr = storage.Create<memgraph::query::NamedExpression>(name, ident);
|
2018-10-18 17:16:32 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
|
|
|
}
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &, ReturnBody &body, Limit limit) { body.limit = limit.expression; }
|
|
|
|
void FillReturnBody(AstStorage &, ReturnBody &body, Skip skip, Limit limit = Limit{}) {
|
2017-04-24 19:51:16 +08:00
|
|
|
body.skip = skip.expression;
|
|
|
|
body.limit = limit.expression;
|
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &, ReturnBody &body, OrderBy order_by, Limit limit = Limit{}) {
|
2017-04-24 19:51:16 +08:00
|
|
|
body.order_by = order_by.expressions;
|
|
|
|
body.limit = limit.expression;
|
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &, ReturnBody &body, OrderBy order_by, Skip skip, Limit limit = Limit{}) {
|
2017-04-24 19:51:16 +08:00
|
|
|
body.order_by = order_by.expressions;
|
|
|
|
body.skip = skip.expression;
|
|
|
|
body.limit = limit.expression;
|
2017-04-20 17:20:20 +08:00
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &, ReturnBody &body, Expression *expr, NamedExpression *named_expr) {
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
// This overload supports `RETURN(expr, AS(name))` construct, since
|
|
|
|
// NamedExpression does not inherit Expression.
|
|
|
|
named_expr->expression_ = expr;
|
2017-04-24 19:51:16 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
2017-03-24 23:50:42 +08:00
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &storage, ReturnBody &body, const std::string &name, NamedExpression *named_expr) {
|
2022-02-22 20:33:45 +08:00
|
|
|
named_expr->expression_ = storage.Create<memgraph::query::Identifier>(name);
|
2017-05-31 20:00:30 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
|
|
|
}
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &storage, ReturnBody &body, Expression *expr, NamedExpression *named_expr, T... rest) {
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
named_expr->expression_ = expr;
|
2017-04-24 19:51:16 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
2017-05-31 20:00:30 +08:00
|
|
|
FillReturnBody(storage, body, rest...);
|
|
|
|
}
|
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &storage, ReturnBody &body, NamedExpression *named_expr, T... rest) {
|
2017-05-31 20:00:30 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
|
|
|
FillReturnBody(storage, body, rest...);
|
|
|
|
}
|
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &storage, ReturnBody &body, const std::string &name, NamedExpression *named_expr,
|
2017-05-31 20:00:30 +08:00
|
|
|
T... rest) {
|
2022-02-22 20:33:45 +08:00
|
|
|
named_expr->expression_ = storage.Create<memgraph::query::Identifier>(name);
|
2017-05-31 20:00:30 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
|
|
|
FillReturnBody(storage, body, rest...);
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
}
|
|
|
|
template <class... T>
|
2021-02-18 22:32:43 +08:00
|
|
|
void FillReturnBody(AstStorage &storage, ReturnBody &body, const std::string &name, T... rest) {
|
2022-02-22 20:33:45 +08:00
|
|
|
auto *ident = storage.Create<memgraph::query::Identifier>(name);
|
|
|
|
auto *named_expr = storage.Create<memgraph::query::NamedExpression>(name, ident);
|
2017-04-24 19:51:16 +08:00
|
|
|
body.named_expressions.emplace_back(named_expr);
|
2017-05-31 20:00:30 +08:00
|
|
|
FillReturnBody(storage, body, rest...);
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
}
|
2017-04-24 19:51:16 +08:00
|
|
|
|
|
|
|
/// Create the return clause with given expressions.
|
|
|
|
///
|
|
|
|
/// The supported expression combination of arguments is:
|
|
|
|
///
|
2017-05-31 20:00:30 +08:00
|
|
|
/// (String | NamedExpression | (Expression NamedExpression))+
|
|
|
|
/// [OrderBy] [Skip] [Limit]
|
2017-04-24 19:51:16 +08:00
|
|
|
///
|
|
|
|
/// When the pair (Expression NamedExpression) is given, the Expression will be
|
|
|
|
/// moved inside the NamedExpression. This is done, so that the constructs like
|
2017-05-31 20:00:30 +08:00
|
|
|
/// RETURN(expr, AS("name"), ...) are supported. Taking a String is a shorthand
|
|
|
|
/// for RETURN(IDENT(string), AS(string), ....).
|
2017-04-24 19:51:16 +08:00
|
|
|
///
|
|
|
|
/// @sa GetWith
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
template <class... T>
|
2018-05-22 22:45:52 +08:00
|
|
|
auto GetReturn(AstStorage &storage, bool distinct, T... exprs) {
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
auto ret = storage.Create<Return>();
|
2017-05-03 20:57:46 +08:00
|
|
|
ret->body_.distinct = distinct;
|
2017-05-31 20:00:30 +08:00
|
|
|
FillReturnBody(storage, ret->body_, exprs...);
|
2017-04-24 19:51:16 +08:00
|
|
|
return ret;
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
}
|
2017-03-24 23:50:42 +08:00
|
|
|
|
2017-04-24 19:51:16 +08:00
|
|
|
/// Create the with clause with given expressions.
|
2017-04-05 20:19:14 +08:00
|
|
|
///
|
2017-04-24 19:51:16 +08:00
|
|
|
/// The supported expression combination is the same as for @c GetReturn.
|
|
|
|
///
|
|
|
|
/// @sa GetReturn
|
2017-04-05 20:19:14 +08:00
|
|
|
template <class... T>
|
2018-05-22 22:45:52 +08:00
|
|
|
auto GetWith(AstStorage &storage, bool distinct, T... exprs) {
|
2017-04-05 20:19:14 +08:00
|
|
|
auto with = storage.Create<With>();
|
2017-05-03 20:57:46 +08:00
|
|
|
with->body_.distinct = distinct;
|
2017-05-31 20:00:30 +08:00
|
|
|
FillReturnBody(storage, with->body_, exprs...);
|
2017-04-24 19:51:16 +08:00
|
|
|
return with;
|
2017-04-05 20:19:14 +08:00
|
|
|
}
|
|
|
|
|
2017-05-02 21:21:04 +08:00
|
|
|
/// Create the UNWIND clause with given named expression.
|
2022-02-22 20:33:45 +08:00
|
|
|
auto GetUnwind(AstStorage &storage, NamedExpression *named_expr) {
|
|
|
|
return storage.Create<memgraph::query::Unwind>(named_expr);
|
|
|
|
}
|
2018-05-22 22:45:52 +08:00
|
|
|
auto GetUnwind(AstStorage &storage, Expression *expr, NamedExpression *as) {
|
2017-05-02 21:21:04 +08:00
|
|
|
as->expression_ = expr;
|
|
|
|
return GetUnwind(storage, as);
|
|
|
|
}
|
|
|
|
|
2017-03-27 20:23:31 +08:00
|
|
|
/// Create the delete clause with given named expressions.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetDelete(AstStorage &storage, std::vector<Expression *> exprs, bool detach = false) {
|
2017-03-27 20:23:31 +08:00
|
|
|
auto del = storage.Create<Delete>();
|
2021-02-18 22:32:43 +08:00
|
|
|
del->expressions_.insert(del->expressions_.begin(), exprs.begin(), exprs.end());
|
2017-03-27 20:23:31 +08:00
|
|
|
del->detach_ = detach;
|
|
|
|
return del;
|
|
|
|
}
|
|
|
|
|
2017-03-28 17:04:28 +08:00
|
|
|
/// Create a set property clause for given property lookup and the right hand
|
|
|
|
/// side expression.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetSet(AstStorage &storage, PropertyLookup *prop_lookup, Expression *expr) {
|
2017-03-28 17:04:28 +08:00
|
|
|
return storage.Create<SetProperty>(prop_lookup, expr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a set properties clause for given identifier name and the right hand
|
|
|
|
/// side expression.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetSet(AstStorage &storage, const std::string &name, Expression *expr, bool update = false) {
|
|
|
|
return storage.Create<SetProperties>(storage.Create<Identifier>(name), expr, update);
|
2017-03-28 17:04:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a set labels clause for given identifier name and labels.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetSet(AstStorage &storage, const std::string &name, std::vector<std::string> label_names) {
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
std::vector<LabelIx> labels;
|
|
|
|
labels.reserve(label_names.size());
|
|
|
|
for (const auto &label : label_names) {
|
|
|
|
labels.push_back(storage.GetLabelIx(label));
|
|
|
|
}
|
2017-03-28 17:04:28 +08:00
|
|
|
return storage.Create<SetLabels>(storage.Create<Identifier>(name), labels);
|
|
|
|
}
|
|
|
|
|
2017-03-30 14:44:56 +08:00
|
|
|
/// Create a remove property clause for given property lookup
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetRemove(AstStorage &storage, PropertyLookup *prop_lookup) { return storage.Create<RemoveProperty>(prop_lookup); }
|
2017-03-30 14:44:56 +08:00
|
|
|
|
|
|
|
/// Create a remove labels clause for given identifier name and labels.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetRemove(AstStorage &storage, const std::string &name, std::vector<std::string> label_names) {
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
std::vector<LabelIx> labels;
|
|
|
|
labels.reserve(label_names.size());
|
|
|
|
for (const auto &label : label_names) {
|
|
|
|
labels.push_back(storage.GetLabelIx(label));
|
|
|
|
}
|
2017-03-30 14:44:56 +08:00
|
|
|
return storage.Create<RemoveLabels>(storage.Create<Identifier>(name), labels);
|
|
|
|
}
|
|
|
|
|
2017-04-26 19:49:41 +08:00
|
|
|
/// Create a Merge clause for given Pattern with optional OnMatch and OnCreate
|
|
|
|
/// parts.
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetMerge(AstStorage &storage, Pattern *pattern, OnCreate on_create = OnCreate{}) {
|
2022-02-22 20:33:45 +08:00
|
|
|
auto *merge = storage.Create<memgraph::query::Merge>();
|
2017-04-26 19:49:41 +08:00
|
|
|
merge->pattern_ = pattern;
|
|
|
|
merge->on_create_ = on_create.set;
|
|
|
|
return merge;
|
|
|
|
}
|
2021-02-18 22:32:43 +08:00
|
|
|
auto GetMerge(AstStorage &storage, Pattern *pattern, OnMatch on_match, OnCreate on_create = OnCreate{}) {
|
2022-02-22 20:33:45 +08:00
|
|
|
auto *merge = storage.Create<memgraph::query::Merge>();
|
2017-04-26 19:49:41 +08:00
|
|
|
merge->pattern_ = pattern;
|
|
|
|
merge->on_match_ = on_match.set;
|
|
|
|
merge->on_create_ = on_create.set;
|
|
|
|
return merge;
|
|
|
|
}
|
|
|
|
|
2022-02-11 18:29:41 +08:00
|
|
|
auto GetCallProcedure(AstStorage &storage, std::string procedure_name,
|
2022-02-22 20:33:45 +08:00
|
|
|
std::vector<memgraph::query::Expression *> arguments = {}) {
|
|
|
|
auto *call_procedure = storage.Create<memgraph::query::CallProcedure>();
|
2022-02-11 18:29:41 +08:00
|
|
|
call_procedure->procedure_name_ = std::move(procedure_name);
|
|
|
|
call_procedure->arguments_ = std::move(arguments);
|
|
|
|
return call_procedure;
|
|
|
|
}
|
|
|
|
|
2023-03-31 21:24:02 +08:00
|
|
|
auto GetCallSubquery(AstStorage &storage, SingleQuery *subquery) {
|
|
|
|
auto *call_subquery = storage.Create<memgraph::query::CallSubquery>();
|
|
|
|
|
|
|
|
auto *query = storage.Create<CypherQuery>();
|
|
|
|
query->single_query_ = std::move(subquery);
|
|
|
|
|
|
|
|
call_subquery->cypher_query_ = std::move(query);
|
|
|
|
|
|
|
|
return call_subquery;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto GetCallSubquery(AstStorage &storage, CypherQuery *subquery) {
|
|
|
|
auto *call_subquery = storage.Create<memgraph::query::CallSubquery>();
|
|
|
|
call_subquery->cypher_query_ = std::move(subquery);
|
|
|
|
|
|
|
|
return call_subquery;
|
|
|
|
}
|
|
|
|
|
2022-04-11 18:55:34 +08:00
|
|
|
/// Create the FOREACH clause with given named expression.
|
|
|
|
auto GetForeach(AstStorage &storage, NamedExpression *named_expr, const std::vector<query::Clause *> &clauses) {
|
|
|
|
return storage.Create<query::Foreach>(named_expr, clauses);
|
|
|
|
}
|
|
|
|
|
2017-03-24 23:50:42 +08:00
|
|
|
} // namespace test_common
|
|
|
|
|
2022-02-22 20:33:45 +08:00
|
|
|
} // namespace memgraph::query
|
2017-03-24 23:50:42 +08:00
|
|
|
|
|
|
|
/// All the following macros implicitly pass `storage` variable to functions.
|
2018-05-22 22:45:52 +08:00
|
|
|
/// You need to have `AstStorage storage;` somewhere in scope to use them.
|
2017-03-24 23:50:42 +08:00
|
|
|
/// Refer to function documentation to see what the macro does.
|
|
|
|
///
|
|
|
|
/// Example usage:
|
|
|
|
///
|
|
|
|
/// // Create MATCH (n) -[r]- (m) RETURN m AS new_name
|
2018-05-22 22:45:52 +08:00
|
|
|
/// AstStorage storage;
|
2017-03-24 23:50:42 +08:00
|
|
|
/// auto query = QUERY(MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))),
|
|
|
|
/// RETURN(NEXPR("new_name"), IDENT("m")));
|
2023-06-29 17:44:55 +08:00
|
|
|
#define NODE(...) memgraph::query::test_common::GetNode(this->storage, __VA_ARGS__)
|
|
|
|
#define EDGE(...) memgraph::query::test_common::GetEdge(this->storage, __VA_ARGS__)
|
|
|
|
#define EDGE_VARIABLE(...) memgraph::query::test_common::GetEdgeVariable(this->storage, __VA_ARGS__)
|
|
|
|
#define PATTERN(...) memgraph::query::test_common::GetPattern(this->storage, {__VA_ARGS__})
|
|
|
|
#define NAMED_PATTERN(name, ...) memgraph::query::test_common::GetPattern(this->storage, name, {__VA_ARGS__})
|
|
|
|
#define OPTIONAL_MATCH(...) \
|
|
|
|
memgraph::query::test_common::GetWithPatterns(this->storage.template Create<memgraph::query::Match>(true), \
|
|
|
|
{__VA_ARGS__})
|
2022-02-22 20:33:45 +08:00
|
|
|
#define MATCH(...) \
|
2023-06-29 17:44:55 +08:00
|
|
|
memgraph::query::test_common::GetWithPatterns(this->storage.template Create<memgraph::query::Match>(), {__VA_ARGS__})
|
|
|
|
#define WHERE(expr) this->storage.template Create<memgraph::query::Where>((expr))
|
2022-02-22 20:33:45 +08:00
|
|
|
#define CREATE(...) \
|
2023-06-29 17:44:55 +08:00
|
|
|
memgraph::query::test_common::GetWithPatterns(this->storage.template Create<memgraph::query::Create>(), {__VA_ARGS__})
|
|
|
|
#define IDENT(...) this->storage.template Create<memgraph::query::Identifier>(__VA_ARGS__)
|
|
|
|
#define LITERAL(val) this->storage.template Create<memgraph::query::PrimitiveLiteral>((val))
|
|
|
|
#define LIST(...) \
|
|
|
|
this->storage.template Create<memgraph::query::ListLiteral>(std::vector<memgraph::query::Expression *>{__VA_ARGS__})
|
|
|
|
#define MAP(...) \
|
|
|
|
this->storage.template Create<memgraph::query::MapLiteral>( \
|
2022-02-22 20:33:45 +08:00
|
|
|
std::unordered_map<memgraph::query::PropertyIx, memgraph::query::Expression *>{__VA_ARGS__})
|
2023-06-29 17:44:55 +08:00
|
|
|
#define MAP_PROJECTION(map_variable, elements) \
|
|
|
|
this->storage.template Create<memgraph::query::MapProjectionLiteral>( \
|
|
|
|
(memgraph::query::Expression *){map_variable}, \
|
2023-05-17 02:05:35 +08:00
|
|
|
std::unordered_map<memgraph::query::PropertyIx, memgraph::query::Expression *>{elements})
|
2023-10-26 03:36:20 +08:00
|
|
|
#define LABELS_TEST(expr, labels) this->storage.template Create<memgraph::query::LabelsTest>(expr, labels)
|
2023-10-25 03:54:42 +08:00
|
|
|
#define PROPERTY_PAIR(dba, property_name) std::make_pair(property_name, dba.NameToProperty(property_name))
|
|
|
|
#define PROPERTY_LOOKUP(dba, ...) memgraph::query::test_common::GetPropertyLookup(this->storage, dba, __VA_ARGS__)
|
2023-06-29 17:44:55 +08:00
|
|
|
#define ALL_PROPERTIES_LOOKUP(expr) memgraph::query::test_common::GetAllPropertiesLookup(this->storage, expr)
|
2023-10-25 03:54:42 +08:00
|
|
|
#define PARAMETER_LOOKUP(token_position) \
|
|
|
|
this->storage.template Create<memgraph::query::ParameterLookup>((token_position))
|
|
|
|
#define NEXPR(name, expr) this->storage.template Create<memgraph::query::NamedExpression>((name), (expr))
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
// AS is alternative to NEXPR which does not initialize NamedExpression with
|
2017-04-05 20:19:14 +08:00
|
|
|
// Expression. It should be used with RETURN or WITH. For example:
|
Make Where and NamedExpression macros easier to use
Summary:
`Where` can now be constructed in a `QUERY`, instead of requiring manual
addition to `Match`. For example:
auto query = QUERY(MATCH(pattern), WHERE(expr), ...);
compared to:
auto match = MATCH(pattern);
match->where_ = WHERE(expr);
auto query = QUERY(match, ...);
Similarly, `AS` can be used instead of `NEXPR` to create
`NamedExpressions` only with a name. This is meant to be used with
`RETURN` which will look at the previous `Expression` and store it
inside `NamedExpression`. For example:
auto ret = RETURN(IDENT("n"), AS("n"),
PROPERTY_LOOKUP("n", prop), AS("prop_val"));
compared to:
auto ret = RETURN(NEXPR("n", IDENT("n")),
NEXPR("prop_val", PROPERTY_LOOKUP("n", prop)));
Reviewers: florijan, mislav.bradac
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D195
2017-03-28 21:39:18 +08:00
|
|
|
// RETURN(IDENT("n"), AS("n")) vs. RETURN(NEXPR("n", IDENT("n"))).
|
2023-06-29 17:44:55 +08:00
|
|
|
#define AS(name) this->storage.template Create<memgraph::query::NamedExpression>((name))
|
|
|
|
#define RETURN(...) memgraph::query::test_common::GetReturn(this->storage, false, __VA_ARGS__)
|
|
|
|
#define WITH(...) memgraph::query::test_common::GetWith(this->storage, false, __VA_ARGS__)
|
|
|
|
#define RETURN_DISTINCT(...) memgraph::query::test_common::GetReturn(this->storage, true, __VA_ARGS__)
|
|
|
|
#define WITH_DISTINCT(...) memgraph::query::test_common::GetWith(this->storage, true, __VA_ARGS__)
|
|
|
|
#define UNWIND(...) memgraph::query::test_common::GetUnwind(this->storage, __VA_ARGS__)
|
2022-02-22 20:33:45 +08:00
|
|
|
#define ORDER_BY(...) memgraph::query::test_common::GetOrderBy(__VA_ARGS__)
|
2017-04-24 19:51:16 +08:00
|
|
|
#define SKIP(expr) \
|
2022-02-22 20:33:45 +08:00
|
|
|
memgraph::query::test_common::Skip { (expr) }
|
2017-04-24 19:51:16 +08:00
|
|
|
#define LIMIT(expr) \
|
2022-02-22 20:33:45 +08:00
|
|
|
memgraph::query::test_common::Limit { (expr) }
|
2023-06-29 17:44:55 +08:00
|
|
|
#define DELETE(...) memgraph::query::test_common::GetDelete(this->storage, {__VA_ARGS__})
|
2022-02-22 20:33:45 +08:00
|
|
|
#define DETACH_DELETE(...) memgraph::query::test_common::GetDelete(storage, {__VA_ARGS__}, true)
|
2023-06-29 17:44:55 +08:00
|
|
|
#define SET(...) memgraph::query::test_common::GetSet(this->storage, __VA_ARGS__)
|
|
|
|
#define REMOVE(...) memgraph::query::test_common::GetRemove(this->storage, __VA_ARGS__)
|
|
|
|
#define MERGE(...) memgraph::query::test_common::GetMerge(this->storage, __VA_ARGS__)
|
2022-02-22 20:33:45 +08:00
|
|
|
#define ON_MATCH(...) \
|
|
|
|
memgraph::query::test_common::OnMatch { \
|
|
|
|
std::vector<memgraph::query::Clause *> { __VA_ARGS__ } \
|
2017-04-26 19:49:41 +08:00
|
|
|
}
|
2022-02-22 20:33:45 +08:00
|
|
|
#define ON_CREATE(...) \
|
|
|
|
memgraph::query::test_common::OnCreate { \
|
|
|
|
std::vector<memgraph::query::Clause *> { __VA_ARGS__ } \
|
2017-04-26 19:49:41 +08:00
|
|
|
}
|
2022-08-02 18:51:22 +08:00
|
|
|
#define CREATE_INDEX_ON(label, property) \
|
2022-02-22 20:33:45 +08:00
|
|
|
storage.Create<memgraph::query::IndexQuery>(memgraph::query::IndexQuery::Action::CREATE, (label), \
|
2022-08-02 18:51:22 +08:00
|
|
|
std::vector<memgraph::query::PropertyIx>{(property)})
|
2023-06-29 17:44:55 +08:00
|
|
|
#define QUERY(...) memgraph::query::test_common::GetQuery(this->storage, __VA_ARGS__)
|
|
|
|
#define SINGLE_QUERY(...) \
|
|
|
|
memgraph::query::test_common::GetSingleQuery(this->storage.template Create<SingleQuery>(), __VA_ARGS__)
|
|
|
|
#define UNION(...) \
|
|
|
|
memgraph::query::test_common::GetCypherUnion(this->storage.template Create<CypherUnion>(true), __VA_ARGS__)
|
|
|
|
#define UNION_ALL(...) \
|
|
|
|
memgraph::query::test_common::GetCypherUnion(this->storage.template Create<CypherUnion>(false), __VA_ARGS__)
|
|
|
|
#define FOREACH(...) memgraph::query::test_common::GetForeach(this->storage, __VA_ARGS__)
|
2017-04-03 20:32:29 +08:00
|
|
|
// Various operators
|
2023-06-29 17:44:55 +08:00
|
|
|
#define NOT(expr) this->storage.template Create<memgraph::query::NotOperator>((expr))
|
|
|
|
#define UPLUS(expr) this->storage.template Create<memgraph::query::UnaryPlusOperator>((expr))
|
|
|
|
#define UMINUS(expr) this->storage.template Create<memgraph::query::UnaryMinusOperator>((expr))
|
|
|
|
#define IS_NULL(expr) this->storage.template Create<memgraph::query::IsNullOperator>((expr))
|
|
|
|
#define ADD(expr1, expr2) this->storage.template Create<memgraph::query::AdditionOperator>((expr1), (expr2))
|
|
|
|
#define LESS(expr1, expr2) this->storage.template Create<memgraph::query::LessOperator>((expr1), (expr2))
|
|
|
|
#define LESS_EQ(expr1, expr2) this->storage.template Create<memgraph::query::LessEqualOperator>((expr1), (expr2))
|
|
|
|
#define GREATER(expr1, expr2) this->storage.template Create<memgraph::query::GreaterOperator>((expr1), (expr2))
|
|
|
|
#define GREATER_EQ(expr1, expr2) this->storage.template Create<memgraph::query::GreaterEqualOperator>((expr1), (expr2))
|
|
|
|
#define SUM(expr, distinct) \
|
|
|
|
this->storage.template Create<memgraph::query::Aggregation>((expr), nullptr, memgraph::query::Aggregation::Op::SUM, \
|
|
|
|
(distinct))
|
|
|
|
#define COUNT(expr, distinct) \
|
|
|
|
this->storage.template Create<memgraph::query::Aggregation>((expr), nullptr, \
|
|
|
|
memgraph::query::Aggregation::Op::COUNT, (distinct))
|
2022-12-03 19:48:44 +08:00
|
|
|
#define AVG(expr, distinct) \
|
|
|
|
storage.Create<memgraph::query::Aggregation>((expr), nullptr, memgraph::query::Aggregation::Op::AVG, (distinct))
|
|
|
|
#define COLLECT_LIST(expr, distinct) \
|
|
|
|
storage.Create<memgraph::query::Aggregation>((expr), nullptr, memgraph::query::Aggregation::Op::COLLECT_LIST, \
|
|
|
|
(distinct))
|
2023-06-29 17:44:55 +08:00
|
|
|
#define EQ(expr1, expr2) this->storage.template Create<memgraph::query::EqualOperator>((expr1), (expr2))
|
|
|
|
#define NEQ(expr1, expr2) this->storage.template Create<memgraph::query::NotEqualOperator>((expr1), (expr2))
|
|
|
|
#define AND(expr1, expr2) this->storage.template Create<memgraph::query::AndOperator>((expr1), (expr2))
|
|
|
|
#define OR(expr1, expr2) this->storage.template Create<memgraph::query::OrOperator>((expr1), (expr2))
|
|
|
|
#define IN_LIST(expr1, expr2) this->storage.template Create<memgraph::query::InListOperator>((expr1), (expr2))
|
2022-02-22 20:33:45 +08:00
|
|
|
#define IF(cond, then, else) storage.Create<memgraph::query::IfOperator>((cond), (then), (else))
|
2017-06-05 17:50:47 +08:00
|
|
|
// Function call
|
2023-06-29 17:44:55 +08:00
|
|
|
#define FN(function_name, ...) \
|
|
|
|
this->storage.template Create<memgraph::query::Function>(memgraph::utils::ToUpperCase(function_name), \
|
|
|
|
std::vector<memgraph::query::Expression *>{__VA_ARGS__})
|
2017-06-05 17:50:47 +08:00
|
|
|
// List slicing
|
2022-02-22 20:33:45 +08:00
|
|
|
#define SLICE(list, lower_bound, upper_bound) \
|
2023-06-29 17:44:55 +08:00
|
|
|
this->storage.template Create<memgraph::query::ListSlicingOperator>(list, lower_bound, upper_bound)
|
2017-07-25 19:01:08 +08:00
|
|
|
// all(variable IN list WHERE predicate)
|
2023-06-29 17:44:55 +08:00
|
|
|
#define ALL(variable, list, where) \
|
|
|
|
this->storage.template Create<memgraph::query::All>( \
|
|
|
|
this->storage.template Create<memgraph::query::Identifier>(variable), list, where)
|
|
|
|
#define SINGLE(variable, list, where) \
|
|
|
|
this->storage.template Create<memgraph::query::Single>( \
|
|
|
|
this->storage.template Create<memgraph::query::Identifier>(variable), list, where)
|
2022-02-22 20:33:45 +08:00
|
|
|
#define ANY(variable, list, where) \
|
|
|
|
storage.Create<memgraph::query::Any>(storage.Create<memgraph::query::Identifier>(variable), list, where)
|
2021-02-18 22:32:43 +08:00
|
|
|
#define NONE(variable, list, where) \
|
2022-02-22 20:33:45 +08:00
|
|
|
storage.Create<memgraph::query::None>(storage.Create<memgraph::query::Identifier>(variable), list, where)
|
2023-06-29 17:44:55 +08:00
|
|
|
#define REDUCE(accumulator, initializer, variable, list, expr) \
|
|
|
|
this->storage.template Create<memgraph::query::Reduce>( \
|
|
|
|
this->storage.template Create<memgraph::query::Identifier>(accumulator), initializer, \
|
|
|
|
this->storage.template Create<memgraph::query::Identifier>(variable), list, expr)
|
|
|
|
#define COALESCE(...) \
|
|
|
|
this->storage.template Create<memgraph::query::Coalesce>(std::vector<memgraph::query::Expression *>{__VA_ARGS__})
|
|
|
|
#define EXTRACT(variable, list, expr) \
|
|
|
|
this->storage.template Create<memgraph::query::Extract>( \
|
|
|
|
this->storage.template Create<memgraph::query::Identifier>(variable), list, expr)
|
|
|
|
#define EXISTS(pattern) this->storage.template Create<memgraph::query::Exists>(pattern)
|
2023-08-02 00:49:11 +08:00
|
|
|
#define AUTH_QUERY(action, user, role, user_or_role, password, database, privileges, labels, edgeTypes) \
|
|
|
|
storage.Create<memgraph::query::AuthQuery>((action), (user), (role), (user_or_role), password, (database), \
|
|
|
|
(privileges), (labels), (edgeTypes))
|
2022-02-22 20:33:45 +08:00
|
|
|
#define DROP_USER(usernames) storage.Create<memgraph::query::DropUser>((usernames))
|
|
|
|
#define CALL_PROCEDURE(...) memgraph::query::test_common::GetCallProcedure(storage, __VA_ARGS__)
|
2023-06-29 17:44:55 +08:00
|
|
|
#define CALL_SUBQUERY(...) memgraph::query::test_common::GetCallSubquery(this->storage, __VA_ARGS__)
|