DISTINCT is now inside AST; tradeoff: [Return object with return list and distinct pointers -> query executor is going to be more complex] OR [ReturnList object and ReturnDistinct object -> lemon / LARL(1) syntax will be much more complex]
This commit is contained in:
parent
2998527462
commit
f79add5633
@ -1,5 +1,6 @@
|
||||
CXX = clang++
|
||||
CXXFLAGS = -std=c++1y
|
||||
# CXXFLAGS = -std=c++1y -g # DEBUG CXXFLAGS
|
||||
INC = -I../
|
||||
|
||||
parser: parser.o cypher.o
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "property.hpp"
|
||||
#include "relationship.hpp"
|
||||
#include "node.hpp"
|
||||
#include "distinct.hpp"
|
||||
#include "return.hpp"
|
||||
#include "pattern.hpp"
|
||||
#include "return.hpp"
|
||||
|
@ -44,6 +44,7 @@ struct Pattern;
|
||||
|
||||
struct Return;
|
||||
struct ReturnList;
|
||||
struct Distinct;
|
||||
|
||||
struct Match;
|
||||
struct Where;
|
||||
@ -58,6 +59,6 @@ struct AstVisitor : public Visitor<Accessor, Boolean, Float, Identifier,
|
||||
Integer, String, Property, And, Or, Lt, Gt, Ge, Le, Eq, Ne, Plus, Minus,
|
||||
Star, Slash, Rem, PropertyList, RelationshipList, Relationship, Node,
|
||||
RelationshipSpecs, LabelList, ReturnList, Pattern, Match, ReadQuery,
|
||||
Start, Where, WriteQuery, Create, Return> {};
|
||||
Start, Where, WriteQuery, Create, Return, Distinct> {};
|
||||
|
||||
}
|
||||
|
17
cypher/ast/distinct.hpp
Normal file
17
cypher/ast/distinct.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "ast_node.hpp"
|
||||
#include "identifier.hpp"
|
||||
|
||||
namespace ast
|
||||
{
|
||||
|
||||
struct Distinct : public AstNode<Distinct>
|
||||
{
|
||||
Distinct(Identifier* identifier)
|
||||
: identifier(identifier) {}
|
||||
|
||||
Identifier* identifier;
|
||||
};
|
||||
|
||||
}
|
@ -5,7 +5,9 @@
|
||||
namespace ast
|
||||
{
|
||||
|
||||
struct Expr : public AstVisitable {};
|
||||
struct Expr : public AstVisitable
|
||||
{
|
||||
};
|
||||
|
||||
template <class Derived>
|
||||
struct VisitableExpr : public Crtp<Derived>, public Expr
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "list.hpp"
|
||||
#include "identifier.hpp"
|
||||
#include "distinct.hpp"
|
||||
|
||||
namespace ast
|
||||
{
|
||||
@ -14,9 +15,17 @@ struct ReturnList : public List<Identifier, ReturnList>
|
||||
struct Return : public AstNode<Return>
|
||||
{
|
||||
Return(ReturnList* return_list)
|
||||
: return_list(return_list) {}
|
||||
: return_list(return_list), distinct(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Return(Distinct* distinct)
|
||||
: return_list(nullptr), distinct(distinct)
|
||||
{
|
||||
}
|
||||
|
||||
ReturnList* return_list;
|
||||
Distinct* distinct;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -13,7 +13,14 @@
|
||||
|
||||
%syntax_error
|
||||
{
|
||||
throw SyntaxError(TOKEN->value);
|
||||
int n = sizeof(yyTokenName) / sizeof(yyTokenName[0]);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
int a = yy_find_shift_action(yypParser, (YYCODETYPE)i);
|
||||
if (a < YYNSTATE + YYNRULE) {
|
||||
printf("possible token: %s\n", yyTokenName[i]);
|
||||
}
|
||||
}
|
||||
// throw SyntaxError(TOKEN->value);
|
||||
}
|
||||
|
||||
%stack_overflow
|
||||
@ -195,11 +202,14 @@ where_clause(W) ::= . {
|
||||
|
||||
%type return_clause {ast::Return*}
|
||||
|
||||
// return clause (return ORDER BY, SKIP, LIMIT)
|
||||
return_clause(R) ::= RETURN return_list(L). {
|
||||
R = ast->create<ast::Return>(L);
|
||||
}
|
||||
|
||||
return_clause(R) ::= RETURN distinct(D). {
|
||||
R = ast->create<ast::Return>(D);
|
||||
}
|
||||
|
||||
%type return_list {ast::ReturnList*}
|
||||
|
||||
return_list(R) ::= return_list(N) COMMA idn(I). {
|
||||
@ -210,6 +220,12 @@ return_list(R) ::= idn(I). {
|
||||
R = ast->create<ast::ReturnList>(I, nullptr);
|
||||
}
|
||||
|
||||
%type distinct {ast::Distinct*}
|
||||
|
||||
distinct(R) ::= DISTINCT idn(I). {
|
||||
R = ast->create<ast::Distinct>(I);
|
||||
}
|
||||
|
||||
%type properties {ast::PropertyList*}
|
||||
|
||||
// '{' <property_list> '}'
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
rule("(?i:WHERE)", TK_WHERE);
|
||||
rule("(?i:RETURN)", TK_RETURN);
|
||||
rule("(?i:CREATE)", TK_CREATE);
|
||||
rule("(?i:DISTINCT)", TK_DISTINCT);
|
||||
|
||||
rule("(?i:AND)", TK_AND);
|
||||
rule("(?i:OR)", TK_OR);
|
||||
|
@ -124,6 +124,12 @@ public:
|
||||
Traverser::visit(return_clause);
|
||||
}
|
||||
|
||||
void visit(ast::Distinct& distinct) override
|
||||
{
|
||||
auto entry = printer.advance("Distinct");
|
||||
Traverser::visit(distinct);
|
||||
}
|
||||
|
||||
void visit(ast::Accessor& accessor) override
|
||||
{
|
||||
auto entry = printer.advance("Accessor");
|
||||
|
@ -8,14 +8,11 @@
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/string/filereader.hpp"
|
||||
|
||||
#include "utils/terminate_handler.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// * QUERY EXAMPLES *
|
||||
// "CREATE (n { name: 'Dominik', age: 24, role: 'CEO' }) return n"
|
||||
// "MATCH (user:User { name: 'Dominik', age: 8 + 4})-[has:HAS|IS|CAN { duration: 'PERMANENT'}]->(item:Item)--(shop)"
|
||||
// "MATCH (user:User { name: 'Dominik', age: 24})-[has:HAS]->(item:Item) WHERE item.name = 'XPS 13' AND item.price = 11999.99 RETURN user, has, item"
|
||||
|
||||
// * INPUT ARGUMENTS *
|
||||
// -q -> query
|
||||
// -v -> visitor
|
||||
@ -33,11 +30,14 @@ std::string extract_query(const vector_str& arguments)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::set_terminate(&terminate_handler);
|
||||
|
||||
// arguments parsing
|
||||
auto arguments = all_arguments(argc, argv);
|
||||
|
||||
// query extraction
|
||||
auto cypher_query = extract_query(arguments);
|
||||
cout << "QUERY: " << cypher_query << endl;
|
||||
|
||||
// traversers
|
||||
auto traverser = get_argument(arguments, "-t", "code");
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
{
|
||||
tokens.emplace_back(tokenizer.lookup());
|
||||
auto& token = tokens.back();
|
||||
// std::cout << token << std::endl;
|
||||
std::cout << token << std::endl;
|
||||
cypher_parser(parser, token.id, &token, &tree);
|
||||
|
||||
} while(tokens.back().id != 0);
|
||||
|
1
cypher/query/read/match/match-custom1.cypher
Normal file
1
cypher/query/read/match/match-custom1.cypher
Normal file
@ -0,0 +1 @@
|
||||
MATCH (user:User { name: 'Dominik', age: 8 + 4})-[has:HAS|IS|CAN { duration: 'PERMANENT'}]->(item:Item)--(shop)
|
1
cypher/query/read/match/match-custom2.cypher
Normal file
1
cypher/query/read/match/match-custom2.cypher
Normal file
@ -0,0 +1 @@
|
||||
MATCH (user:User { name: 'Dominik', age: 24})-[has:HAS]->(item:Item) WHERE item.name = 'XPS 13' AND item.price = 11999.99 RETURN user, has, item
|
1
cypher/query/read/return/return-alias.cypher
Normal file
1
cypher/query/read/return/return-alias.cypher
Normal file
@ -0,0 +1 @@
|
||||
MATCH (n) RETURN n AS columnName
|
1
cypher/query/read/return/return-all.cypher
Normal file
1
cypher/query/read/return/return-all.cypher
Normal file
@ -0,0 +1 @@
|
||||
MATCH (n) RETURN n
|
1
cypher/query/read/return/return-count.cypher
Normal file
1
cypher/query/read/return/return-count.cypher
Normal file
@ -0,0 +1 @@
|
||||
RETURN count(*)
|
1
cypher/query/read/return/return-distinct.cypher
Normal file
1
cypher/query/read/return/return-distinct.cypher
Normal file
@ -0,0 +1 @@
|
||||
MATCH (n) RETURN DISTINCT n
|
1
cypher/query/read/return/return-limit.cypher
Normal file
1
cypher/query/read/return/return-limit.cypher
Normal file
@ -0,0 +1 @@
|
||||
LIMIT 10
|
1
cypher/query/read/return/return-order-asc.cypher
Normal file
1
cypher/query/read/return/return-order-asc.cypher
Normal file
@ -0,0 +1 @@
|
||||
ORDER BY n.property
|
1
cypher/query/read/return/return-order-desc.cypher
Normal file
1
cypher/query/read/return/return-order-desc.cypher
Normal file
@ -0,0 +1 @@
|
||||
ORDER BY n.property DESC
|
1
cypher/query/read/return/return-skip-limit.cypher
Normal file
1
cypher/query/read/return/return-skip-limit.cypher
Normal file
@ -0,0 +1 @@
|
||||
SKIP 2 LIMIT 3
|
1
cypher/query/read/return/return-skip.cypher
Normal file
1
cypher/query/read/return/return-skip.cypher
Normal file
@ -0,0 +1 @@
|
||||
SKIP 10
|
1
cypher/query/read/union/union-all.cypher
Normal file
1
cypher/query/read/union/union-all.cypher
Normal file
@ -0,0 +1 @@
|
||||
MATCH (a)-[:KNOWS]->(b) RETURN b.name UNION ALL MATCH (a)-[:LOVES]->(b) RETURN b.name
|
1
cypher/query/read/union/union.cypher
Normal file
1
cypher/query/read/union/union.cypher
Normal file
@ -0,0 +1 @@
|
||||
MATCH (a)-[:KNOWS]->(b) RETURN b.name UNION MATCH (a)-[:LOVES]->(b) RETURN b.name
|
@ -1 +1 @@
|
||||
WHERE n.property <> {value}
|
||||
MATCH n WHERE n.property <> "100"
|
||||
|
@ -1 +1 @@
|
||||
CREATE (n {name: 'Domko', age: 24}) RETURN n
|
||||
CREATE (n {name: 'Domko', age: 26}) RETURN n
|
||||
|
@ -44,7 +44,10 @@ public:
|
||||
|
||||
void visit(ast::Return& return_clause) override
|
||||
{
|
||||
if (return_clause.return_list != nullptr)
|
||||
accept(return_clause.return_list);
|
||||
if (return_clause.distinct != nullptr)
|
||||
accept(return_clause.distinct);
|
||||
}
|
||||
|
||||
void visit(ast::Accessor& accessor) override
|
||||
@ -188,6 +191,11 @@ public:
|
||||
accept(create.pattern);
|
||||
}
|
||||
|
||||
void visit(ast::Distinct& distinct) override
|
||||
{
|
||||
accept(distinct.identifier);
|
||||
}
|
||||
|
||||
protected:
|
||||
template<class T>
|
||||
void accept(T* node)
|
||||
|
@ -23,8 +23,8 @@ int main()
|
||||
container.singleton<Db>();
|
||||
|
||||
auto loop = container.singleton<uv::UvLoop>();
|
||||
auto app = container.singleton<sp::Speedy, uv::UvLoop>("/db/data");
|
||||
|
||||
auto app = container.singleton<sp::Speedy, uv::UvLoop>("/db/data");
|
||||
container.singleton<Pool>(4);
|
||||
container.singleton<Task, uv::UvLoop, Pool>();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user