First implementation of delete query

This commit is contained in:
Marko Budiselic 2016-01-24 16:21:46 +01:00
parent 1a6676e240
commit 7c52817e41
14 changed files with 161 additions and 37 deletions

View File

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

20
cypher/ast/alias.hpp Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <string>
#include "ast_node.hpp"
namespace ast
{
// TODO: set identifier as base class
struct Alias : public AstNode<Alias>
{
Alias(std::string name, std::string alias)
: name(name), alias(alias) {}
std::string name;
std::string alias;
};
}

View File

@ -3,6 +3,7 @@
#include "accessor.hpp"
#include "values.hpp"
#include "identifier.hpp"
#include "alias.hpp"
#include "operators.hpp"
#include "property.hpp"
#include "relationship.hpp"
@ -11,6 +12,7 @@
#include "return.hpp"
#include "pattern.hpp"
#include "return.hpp"
#include "delete.hpp"
#include "match.hpp"
#include "queries.hpp"
#include "start.hpp"

View File

@ -6,6 +6,7 @@ namespace ast
{
struct Identifier;
struct Alias;
// properties
struct Property;
@ -45,6 +46,7 @@ struct Pattern;
struct Return;
struct ReturnList;
struct Distinct;
struct Delete;
struct Match;
struct Where;
@ -52,13 +54,15 @@ struct Where;
struct Start;
struct ReadQuery;
struct WriteQuery;
struct DeleteQuery;
struct Create;
struct AstVisitor : public Visitor<Accessor, Boolean, Float, Identifier,
struct AstVisitor : public Visitor<Accessor, Boolean, Float, Identifier, Alias,
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, Distinct> {};
Start, Where, WriteQuery, Create, Return, Distinct, Delete,
DeleteQuery> {};
}

17
cypher/ast/delete.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "ast_node.hpp"
#include "identifier.hpp"
namespace ast
{
struct Delete : public AstNode<Delete>
{
Delete(Identifier* identifier)
: identifier(identifier) {}
Identifier* identifier;
};
}

View File

@ -9,11 +9,10 @@ namespace ast
struct Identifier : public AstNode<Identifier>
{
Identifier(std::string name, std::string alias)
: name(name), alias(alias) {}
Identifier(std::string name)
: name(name) {}
std::string name;
std::string alias;
};
}

View File

@ -4,6 +4,7 @@
#include "match.hpp"
#include "return.hpp"
#include "create.hpp"
#include "delete.hpp"
namespace ast
{
@ -26,4 +27,13 @@ struct WriteQuery : public AstNode<WriteQuery>
Return* return_clause;
};
struct DeleteQuery : public AstNode<DeleteQuery>
{
DeleteQuery(Match* match, Delete* delete_clause)
: match(match), delete_clause(delete_clause) {}
Match* match;
Delete* delete_clause;
};
}

View File

@ -8,12 +8,26 @@ namespace ast
struct Start : public AstNode<Start>
{
Start(ReadQuery* read_query, WriteQuery* write_query)
: read_query(read_query), write_query(write_query) {}
Start(ReadQuery* read_query)
: read_query(read_query)
{
}
ReadQuery* read_query;
WriteQuery* write_query;
// ReadWriteQuery* read_write_query;
Start(WriteQuery* write_query)
: write_query(write_query)
{
}
Start(DeleteQuery* delete_query)
: delete_query(delete_query)
{
}
// TODO: the start structure must have a different implementation
// is this class necessary?
ReadQuery* read_query{nullptr};
WriteQuery* write_query{nullptr};
DeleteQuery* delete_query{nullptr};
};
};

View File

@ -15,12 +15,12 @@
{
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]);
}
int a = yy_find_shift_action(yypParser, (YYCODETYPE)i);
if (a < YYNSTATE + YYNRULE) {
printf("possible token: %s\n", yyTokenName[i]);
}
}
// throw SyntaxError(TOKEN->value);
throw SyntaxError(TOKEN->value);
}
%stack_overflow
@ -53,15 +53,30 @@
%left PLUS MINUS.
%left STAR SLASH REM.
// start structure
start ::= read_query(RQ). {
ast->root = ast->create<ast::Start>(RQ, nullptr);
ast->root = ast->create<ast::Start>(RQ);
}
start ::= write_query(WQ). {
ast->root = ast->create<ast::Start>(nullptr, WQ);
ast->root = ast->create<ast::Start>(WQ);
}
start ::= delete_query(DQ). {
ast->root = ast->create<ast::Start>(DQ);
}
// read query structure
%type read_query {ast::ReadQuery*}
read_query(RQ) ::= match_clause(M) return_clause(R). {
RQ = ast->create<ast::ReadQuery>(M, R);
}
// write query structure
%type write_query {ast::WriteQuery*}
write_query(WQ) ::= create_clause(C) return_clause(R). {
@ -72,28 +87,34 @@ write_query(WQ) ::= create_clause(C). {
WQ = ast->create<ast::WriteQuery>(C, nullptr);
}
// delete query structure
%type delete_query {ast::DeleteQuery*}
delete_query(DQ) ::= match_clause(M) delete_clause(D). {
DQ = ast->create<ast::DeleteQuery>(M, D);
}
%type create_clause {ast::Create*}
create_clause(C) ::= CREATE pattern(P). {
C = ast->create<ast::Create>(P);
}
// read query structure
%type read_query {ast::ReadQuery*}
read_query(RQ) ::= match_clause(M) return_clause(R). {
RQ = ast->create<ast::ReadQuery>(M, R);
}
%type match_clause {ast::Match*}
match_clause(M) ::= MATCH pattern(P) where_clause(W). {
M = ast->create<ast::Match>(P, W);
}
%type delete_clause {ast::Delete*}
// TODO: add DETACH DELETE
delete_clause(D) ::= DELETE idn(I). {
D = ast->create<ast::Delete>(I);
}
%type pattern {ast::Pattern*}
// pattern specification
pattern(P) ::= node(N) rel(R) pattern(NEXT). {
P = ast->create<ast::Pattern>(N, R, NEXT);
}
@ -102,6 +123,9 @@ pattern(P) ::= node(N). {
P = ast->create<ast::Pattern>(N, nullptr, nullptr);
}
// update query
// MATCH ... WITH ... SET ... RETURN
%type rel {ast::Relationship*}
rel(R) ::= MINUS rel_spec(S) MINUS. { // bidirectional
@ -316,15 +340,14 @@ expr(E) ::= idn(I) DOT idn(P). {
%type idn {ast::Identifier*}
idn(I) ::= IDN(X). {
I = ast->create<ast::Identifier>(X->value, "");
I = ast->create<ast::Identifier>(X->value);
}
/*
not the best idea TODO: how to put AS into the grammar
*/
idn(I) ::= IDN(X) AS IDN(A). {
I = ast->create<ast::Identifier>(X->value, A->value);
}
//%type alias {ast::Alias*}
//
//alias(A) ::= IDN(X) AS IDN(Y). {
// A = ast->create<ast::Alias>(X->value, Y->value);
//}
expr(E) ::= INT(V). {
auto value = std::stoi(V->value);

View File

@ -47,6 +47,7 @@ public:
rule("(?i:MATCH)", TK_MATCH);
rule("(?i:WHERE)", TK_WHERE);
rule("(?i:RETURN)", TK_RETURN);
rule("(?i:DELETE)", TK_DELETE);
rule("(?i:CREATE)", TK_CREATE);
rule("(?i:DISTINCT)", TK_DISTINCT);

View File

@ -112,11 +112,16 @@ public:
Traverser::visit(node);
}
void visit(ast::Alias& alias) override
{
auto entry = printer.advance();
entry << "Alias: '" << alias.name << "' AS '" << alias.alias << "'";
}
void visit(ast::Identifier& idn) override
{
auto entry = printer.advance();
entry << "Identifier '" << idn.name << "'";
entry << " Alias '" << idn.alias << "'";
}
void visit(ast::Return& return_clause) override
@ -294,6 +299,18 @@ public:
Traverser::visit(write_query);
}
void visit(ast::DeleteQuery& delete_query) override
{
auto entry = printer.advance("Delete Query");
Traverser::visit(delete_query);
}
void visit(ast::Delete& delete_clause) override
{
auto entry = printer.advance("Delete");
Traverser::visit(delete_clause);
}
void visit(ast::Create& create) override
{
auto entry = printer.advance("Create");

View File

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

View File

@ -0,0 +1 @@
MATCH (n:Person) WHERE n.name="Alice" DELETE n

View File

@ -12,8 +12,18 @@ public:
void visit(ast::Start& start) override
{
accept(start.read_query);
accept(start.write_query);
if (start.read_query != nullptr)
accept(start.read_query);
if (start.read_query != nullptr)
accept(start.write_query);
if (start.delete_query != nullptr)
accept(start.delete_query);
}
void visit(ast::DeleteQuery& delete_query) override
{
accept(delete_query.match);
accept(delete_query.delete_clause);
}
void visit(ast::ReadQuery& read_query) override
@ -196,6 +206,11 @@ public:
accept(distinct.identifier);
}
void visit(ast::Delete& delete_clause) override
{
accept(delete_clause.identifier);
}
protected:
template<class T>
void accept(T* node)