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:
Marko Budiselic 2016-01-18 00:41:54 +01:00
parent 2998527462
commit f79add5633
28 changed files with 96 additions and 21 deletions

View File

@ -1,5 +1,6 @@
CXX = clang++
CXXFLAGS = -std=c++1y
# CXXFLAGS = -std=c++1y -g # DEBUG CXXFLAGS
INC = -I../
parser: parser.o cypher.o

View File

@ -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"

View File

@ -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
View 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;
};
}

View File

@ -5,7 +5,9 @@
namespace ast
{
struct Expr : public AstVisitable {};
struct Expr : public AstVisitable
{
};
template <class Derived>
struct VisitableExpr : public Crtp<Derived>, public Expr

View File

@ -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;
};
};

View File

@ -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> '}'

View File

@ -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);

View File

@ -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");

View File

@ -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");

View File

@ -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);

View File

@ -0,0 +1 @@
MATCH (user:User { name: 'Dominik', age: 8 + 4})-[has:HAS|IS|CAN { duration: 'PERMANENT'}]->(item:Item)--(shop)

View 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

View File

@ -0,0 +1 @@
MATCH (n) RETURN n AS columnName

View File

@ -0,0 +1 @@
MATCH (n) RETURN n

View File

@ -0,0 +1 @@
RETURN count(*)

View File

@ -0,0 +1 @@
MATCH (n) RETURN DISTINCT n

View File

@ -0,0 +1 @@
LIMIT 10

View File

@ -0,0 +1 @@
ORDER BY n.property

View File

@ -0,0 +1 @@
ORDER BY n.property DESC

View File

@ -0,0 +1 @@
SKIP 2 LIMIT 3

View File

@ -0,0 +1 @@
SKIP 10

View File

@ -0,0 +1 @@
MATCH (a)-[:KNOWS]->(b) RETURN b.name UNION ALL MATCH (a)-[:LOVES]->(b) RETURN b.name

View File

@ -0,0 +1 @@
MATCH (a)-[:KNOWS]->(b) RETURN b.name UNION MATCH (a)-[:LOVES]->(b) RETURN b.name

View File

@ -1 +1 @@
WHERE n.property <> {value}
MATCH n WHERE n.property <> "100"

View File

@ -1 +1 @@
CREATE (n {name: 'Domko', age: 24}) RETURN n
CREATE (n {name: 'Domko', age: 26}) RETURN n

View File

@ -44,7 +44,10 @@ public:
void visit(ast::Return& return_clause) override
{
accept(return_clause.return_list);
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)

View File

@ -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>();