diff --git a/CMakeLists.txt b/CMakeLists.txt index 845512a0..554580d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) project(JasmineGraph) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -39,6 +39,14 @@ set(HEADERS globals.h src/query/algorithms/linkprediction/JasminGraphLinkPredictor.h src/query/algorithms/triangles/Triangles.h src/query/algorithms/triangles/StreamingTriangles.h + src/query/processor/cypher/astbuilder/ASTBuilder.h + src/query/processor/cypher/astbuilder/ASTInternalNode.h + src/query/processor/cypher/astbuilder/ASTLeafNoValue.h + src/query/processor/cypher/astbuilder/ASTNode.h + src/query/processor/cypher/astbuilder/ASTLeafValue.h + src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.h + src/query/processor/cypher/semanticanalyzer/Scope.h + src/query/processor/cypher/semanticanalyzer/ScopeManager.h src/scale/scaler.h src/server/JasmineGraphInstance.h src/server/JasmineGraphInstanceFileTransferService.h @@ -71,6 +79,7 @@ set(HEADERS globals.h src/streamingdb/StreamingSQLiteDBInterface.h src/frontend/core/executor/impl/PageRankExecutor.h src/util/dbinterface/DBInterface.h + src/query/processor/cypher/util/Const.h ) set(SOURCES src/backend/JasmineGraphBackend.cpp @@ -106,6 +115,14 @@ set(SOURCES src/backend/JasmineGraphBackend.cpp src/query/algorithms/linkprediction/JasminGraphLinkPredictor.cpp src/query/algorithms/triangles/Triangles.cpp src/query/algorithms/triangles/StreamingTriangles.cpp + src/query/processor/cypher/astbuilder/ASTBuilder.cpp + src/query/processor/cypher/astbuilder/ASTInternalNode.cpp + src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp + src/query/processor/cypher/astbuilder/ASTNode.cpp + src/query/processor/cypher/astbuilder/ASTLeafValue.cpp + src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.cpp + src/query/processor/cypher/semanticanalyzer/Scope.cpp + src/query/processor/cypher/semanticanalyzer/ScopeManager.cpp src/scale/scaler.cpp src/server/JasmineGraphInstance.cpp src/server/JasmineGraphInstanceFileTransferService.cpp @@ -131,13 +148,16 @@ set(SOURCES src/backend/JasmineGraphBackend.cpp src/streamingdb/StreamingSQLiteDBInterface.cpp src/frontend/core/executor/impl/PageRankExecutor.cpp src/util/dbinterface/DBInterface.cpp + src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.cpp + src/query/processor/cypher/util/Const.cpp ) if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") add_compile_options(-DUNIT_TEST) endif () -add_library(JasmineGraphLib ${HEADERS} ${SOURCES}) +file(GLOB GENERATED_SRC /home/ubuntu/software/antlr/*.cpp) +add_library(JasmineGraphLib ${HEADERS} ${SOURCES} ${GENERATED_SRC}) add_executable(JasmineGraph main.h main.cpp) target_compile_definitions(JasmineGraphLib PUBLIC ROOT_DIR="${CMAKE_CURRENT_SOURCE_DIR}/") @@ -162,11 +182,15 @@ target_link_libraries(JasmineGraphLib PRIVATE /usr/local/lib/libcppkafka.so) target_link_libraries(JasmineGraph JasmineGraphLib) target_link_libraries(JasmineGraph curl) +include_directories(/usr/local/include/antlr4-runtime) +link_directories(/usr/local/lib) include_directories(/usr/local/include/yaml-cpp) target_link_libraries(JasmineGraphLib PRIVATE m) target_link_libraries(JasmineGraphLib PRIVATE /usr/local/lib/libkubernetes.so) target_link_libraries(JasmineGraphLib PRIVATE yaml-cpp) target_link_libraries(JasmineGraphLib PRIVATE curl) +target_link_libraries(JasmineGraphLib PRIVATE antlr4-runtime) + if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") # Include google test diff --git a/Dockerfile b/Dockerfile index 5d29c35e..c9d6ac3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,6 +16,8 @@ RUN if [ "$DEBUG" = "true" ]; then apt-get update \ && apt-get install --no-install-recommends -y gdb gdbserver \ && apt-get clean; fi + +WORKDIR "${JASMINEGRAPH_HOME}" COPY ./build.sh ./build.sh COPY ./CMakeLists.txt ./CMakeLists.txt COPY ./main.h ./main.h diff --git a/src/frontend/JasmineGraphFrontEnd.cpp b/src/frontend/JasmineGraphFrontEnd.cpp index d9d02bdd..74742cb5 100644 --- a/src/frontend/JasmineGraphFrontEnd.cpp +++ b/src/frontend/JasmineGraphFrontEnd.cpp @@ -45,6 +45,13 @@ limitations under the License. #include "JasmineGraphFrontEndProtocol.h" #include "core/CoreConstants.h" #include "core/scheduler/JobScheduler.h" +#include "antlr4-runtime.h" +#include "/home/ubuntu/software/antlr/CypherLexer.h" +#include "/home/ubuntu/software/antlr/CypherParser.h" +#include "../query/processor/cypher/astbuilder/ASTBuilder.h" +#include "../query/processor/cypher/astbuilder/ASTNode.h" +#include "../query/processor/cypher/semanticanalyzer/SemanticAnalyzer.h" + #define MAX_PENDING_CONNECTIONS 10 #define DATA_BUFFER_SIZE (FRONTEND_DATA_LENGTH + 1) @@ -64,6 +71,7 @@ bool JasmineGraphFrontEnd::strian_exit; static std::string getPartitionCount(std::string path); static void list_command(int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); +static void cypher_ast_command(int connFd, bool *loop_exit_p); static void add_rdf_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); static void add_graph_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); static void add_graph_cust_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); @@ -169,7 +177,9 @@ void *frontendservicesesion(void *dummyPt) { break; } else if (line.compare(LIST) == 0) { list_command(connFd, sqlite, &loop_exit); - } else if (line.compare(SHTDN) == 0) { + } else if (line.compare(CYPHER_AST) == 0){ + cypher_ast_command(connFd, &loop_exit); + }else if (line.compare(SHTDN) == 0) { JasmineGraphServer::shutdown_workers(); close(connFd); exit(0); @@ -627,6 +637,53 @@ static void list_command(int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_ } } +static void cypher_ast_command(int connFd, bool *loop_exit) +{ + + string msg_1 = "Input Query :"; + int result_wr = write(connFd, msg_1.c_str(), msg_1.length()); + if (result_wr < 0) { + frontend_logger.error("Error writing to socket"); + *loop_exit = true; + return; + } + result_wr = write(connFd, "\r\n", 2); + if (result_wr < 0) { + frontend_logger.error("Error writing to socket"); + *loop_exit = true; + return; + } + + // Get user response. + char user_res[FRONTEND_DATA_LENGTH + 1]; + bzero(user_res, FRONTEND_DATA_LENGTH + 1); + read(connFd, user_res, FRONTEND_DATA_LENGTH); + string user_res_s(user_res); + + antlr4::ANTLRInputStream input(user_res_s); + // Create a lexer from the input + CypherLexer lexer(&input); + + // Create a token stream from the lexer + antlr4::CommonTokenStream tokens(&lexer); + + // Create a parser from the token stream + CypherParser parser(&tokens); + + ASTBuilder ast_builder; + auto* ast = any_cast(ast_builder.visitOC_Cypher(parser.oC_Cypher())); + + SemanticAnalyzer semantic_analyzer; + if(semantic_analyzer.analyze(ast)) + { + frontend_logger.log("AST is successfully analyzed", "log"); + }else + { + frontend_logger.log(user_res, "error"); + frontend_logger.error("query isn't semantically correct"); + } +} + static void add_rdf_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p) { // add RDF graph int result_wr = write(connFd, SEND.c_str(), FRONTEND_COMMAND_LENGTH); @@ -804,7 +861,8 @@ static void add_graph_command(std::string masterIP, int connFd, SQLiteDBInterfac int result_wr = write(connFd, DONE.c_str(), DONE.size()); if (result_wr < 0) { frontend_logger.error("Error writing to socket"); - *loop_exit_p = true; + *loop_exit_p = + true; return; } result_wr = write(connFd, "\r\n", 2); diff --git a/src/frontend/JasmineGraphFrontEndProtocol.cpp b/src/frontend/JasmineGraphFrontEndProtocol.cpp index b8220750..ec8251f4 100644 --- a/src/frontend/JasmineGraphFrontEndProtocol.cpp +++ b/src/frontend/JasmineGraphFrontEndProtocol.cpp @@ -54,4 +54,5 @@ const string SLA = "sla"; const string COMMAND = "command"; const string PRIORITY = "priority(>=1)"; const string INVALID_FORMAT = "Invalid message format"; +const string CYPHER_AST = "cypher-ast"; diff --git a/src/frontend/JasmineGraphFrontEndProtocol.h b/src/frontend/JasmineGraphFrontEndProtocol.h index ad1ac85f..77ee8837 100644 --- a/src/frontend/JasmineGraphFrontEndProtocol.h +++ b/src/frontend/JasmineGraphFrontEndProtocol.h @@ -87,6 +87,7 @@ extern const string STOP_STRIAN; extern const string ADMDL; extern const string MERGE; extern const string INVALID_FORMAT; +extern const string CYPHER_AST; class JasminGraphFrontEndProtocol { // Note that this protocol do not need a handshake session since the communication in most of the time is conducted diff --git a/src/localstore/JasmineGraphHashMapLocalStore.cpp b/src/localstore/JasmineGraphHashMapLocalStore.cpp index 0d5da271..d9aa1a06 100644 --- a/src/localstore/JasmineGraphHashMapLocalStore.cpp +++ b/src/localstore/JasmineGraphHashMapLocalStore.cpp @@ -222,7 +222,7 @@ void JasmineGraphHashMapLocalStore::toLocalAttributeMap(const AttributeStore *at auto entry = allEntries->Get(i); long key = entry->key(); auto attributes = entry->value(); - auto attributesSize = attributes->Length(); + auto attributesSize = attributes->size(); for (int j = 0; j < attributesSize; j = j + 1) { attributeVector.push_back(attributes->Get(j)->c_str()); } diff --git a/src/localstore/incremental/JasmineGraphIncrementalLocalStore.cpp b/src/localstore/incremental/JasmineGraphIncrementalLocalStore.cpp index d4a1165d..6b189513 100644 --- a/src/localstore/incremental/JasmineGraphIncrementalLocalStore.cpp +++ b/src/localstore/incremental/JasmineGraphIncrementalLocalStore.cpp @@ -44,6 +44,7 @@ std::pair JasmineGraphIncrementalLocalStore::getIDs(s "Could be due to JSON parsing error or error while persisting the data to disk", "error"); } + return {"", 0}; // all plath of the function must return std::pair type object even there is an error } void JasmineGraphIncrementalLocalStore::addEdgeFromString(std::string edgeString) { diff --git a/src/partitioner/local/MetisPartitioner.cpp b/src/partitioner/local/MetisPartitioner.cpp index 83094791..205275f3 100644 --- a/src/partitioner/local/MetisPartitioner.cpp +++ b/src/partitioner/local/MetisPartitioner.cpp @@ -301,6 +301,8 @@ std::vector> MetisPartitioner::partitioneWithGPMetis( perror("Popen error in executing gpmetis command"); partitioner_logger.log("Popen error in executing gpmetis command", "error"); } + + return std::vector>{}; // Return an empty vector in case of error } void MetisPartitioner::createPartitionFiles(std::map partMap) { diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp new file mode 100644 index 00000000..fc48f494 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp @@ -0,0 +1,1702 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTBuilder.h" +#include +#include +#include "ASTInternalNode.h" +#include "ASTLeafNoValue.h" +#include "ASTLeafValue.h" +#include "/home/ubuntu/software/antlr/CypherBaseVisitor.h" +#include "../util/Const.h" + +any visitOC_Cypher(CypherParser::OC_CypherContext *ctx) ; + +any visitOC_Statement(CypherParser::OC_StatementContext *ctx) ; + +any visitOC_Query(CypherParser::OC_QueryContext *ctx) ; + +any visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) ; + +any visitOC_Union(CypherParser::OC_UnionContext *ctx) ; + +any visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) ; + +any visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) ; + +any visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) ; + +any visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) ; + +any visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) ; + +any visitOC_Match(CypherParser::OC_MatchContext *ctx) ; + +any visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) ; + +any visitOC_Merge(CypherParser::OC_MergeContext *ctx) ; + +any visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) ; + +any visitOC_Create(CypherParser::OC_CreateContext *ctx) ; + +any visitOC_Set(CypherParser::OC_SetContext *ctx) ; + +any visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) ; + +any visitOC_Delete(CypherParser::OC_DeleteContext *ctx) ; + +any visitOC_Remove(CypherParser::OC_RemoveContext *ctx) ; + +any visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) ; + +any visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) ; + +any visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) ; + +any visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) ; + +any visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) ; + +any visitOC_With(CypherParser::OC_WithContext *ctx) ; + +any visitOC_Return(CypherParser::OC_ReturnContext *ctx) ; + +any visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) ; + +any visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) ; + +any visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) ; + +any visitOC_Order(CypherParser::OC_OrderContext *ctx) ; + +any visitOC_Skip(CypherParser::OC_SkipContext *ctx) ; + +any visitOC_Limit(CypherParser::OC_LimitContext *ctx) ; + +any visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) ; + +any visitOC_Where(CypherParser::OC_WhereContext *ctx) ; + +any visitOC_Pattern(CypherParser::OC_PatternContext *ctx) ; + +any visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) ; + +any visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) ; + +any visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) ; + +any visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) ; + +any visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) ; + +any visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) ; + +any visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) ; + +any visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) ; + +any visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) ; + +any visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) ; + + +any visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) ; + +any visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) ; + +any visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) ; + +any visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) ; + +any visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) ; + +any visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) ; + +any visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) ; + +any visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) ; + +any visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) ; + +any visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) ; + +any visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) ; + +any visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) ; + +any visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) ; + +any visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) ; + +any visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) ; + +any visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) ; + +any visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) ; + +any visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) ; + +any visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) ; + +any visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) ; + +any visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) ; + +any visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) ; + +any visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) ; + +any visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) ; + +any visitOC_Atom(CypherParser::OC_AtomContext *ctx) ; + +any visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) ; + +any visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) ; + +any visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) ; + +any visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) ; + +any visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) ; + +any visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) ; + +any visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) ; + +any visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) ; + +any visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) ; + +any visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) ; + +any visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) ; + +any visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) ; + +any visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) ; + +any visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) ; + +any visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) ; + +any visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) ; + +any visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) ; + +any visitOC_Variable(CypherParser::OC_VariableContext *ctx) ; + +any visitOC_Literal(CypherParser::OC_LiteralContext *ctx) ; + +any visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) ; + +any visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) ; + +any visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) ; + +any visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) ; + +any visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) ; + +any visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) ; + +any visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) ; + +any visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) ; + +any visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) ; + +any visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) ; + +any visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) ; + +any visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) ; + +any visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) ; + +any visitOC_Dash(CypherParser::OC_DashContext *ctx) ; + + + +any ASTBuilder::visitOC_Cypher(CypherParser::OC_CypherContext *ctx) { + return visitOC_Statement(ctx->oC_Statement()); +} + + +any ASTBuilder::visitOC_Statement(CypherParser::OC_StatementContext *ctx) { + return visitOC_Query(ctx->oC_Query()); +} + + +any ASTBuilder::visitOC_Query(CypherParser::OC_QueryContext *ctx) { + if(ctx->oC_RegularQuery()) + { + return visitOC_RegularQuery(ctx->oC_RegularQuery()); + } + return visitOC_StandaloneCall(ctx->oC_StandaloneCall()); +} + + +any ASTBuilder::visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) { + if(!ctx->oC_Union().empty()) + { + auto *node = new ASTInternalNode(Const::UNION); + node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); + for(CypherParser::OC_UnionContext* element : ctx->oC_Union()) + { + node->addElements(any_cast(visitOC_Union(element))); + } + return static_cast(node); + } + return visitOC_SingleQuery(ctx->oC_SingleQuery()); +} + + +any ASTBuilder::visitOC_Union(CypherParser::OC_UnionContext *ctx) { + if(ctx->ALL()) + { + auto *node = new ASTInternalNode(Const::ALL); + node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); + return static_cast(node); + } + return visitOC_SingleQuery(ctx->oC_SingleQuery()); +} + + +any ASTBuilder::visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) { + if(ctx->oC_MultiPartQuery()) + { + return visitOC_MultiPartQuery(ctx->oC_MultiPartQuery()); + } + return visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()); +} + + +any ASTBuilder::visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) { + auto *queryNode = new ASTInternalNode(Const::SINGLE_QUERY); + for (CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) { + queryNode->addElements(any_cast(visitOC_ReadingClause(element))); + } + + for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()){ + queryNode->addElements(any_cast(visitOC_UpdatingClause(element))); + } + + if(ctx->oC_Return()) + { + queryNode->addElements(any_cast(visitOC_Return(ctx->oC_Return()))); + } + return static_cast(queryNode); +} + +any ASTBuilder::visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) { + auto *node = new ASTInternalNode(Const::MULTI_PART_QUERY); + auto *newNode = new ASTInternalNode(Const::SINGLE_QUERY); + + int withIndex = 0; + int readIndex = 0; + int updateIndex = 0; + + for (int i = 0; i < ctx->children.size(); i++) { + auto *child = ctx->children[i]; + string typeName = typeid(*child).name(); + string grammarName = typeName.substr(17); + + if (i + 1 < ctx->children.size()) { + auto *nextChild = ctx->children[i + 1]; + string nextTypeName = typeid(*nextChild).name(); + string nextGrammarName = nextTypeName.substr(17); + + if (grammarName == "OC_WithContextE" && nextGrammarName == "OC_SinglePartQueryContextE") { + newNode->addElements(any_cast(visitOC_With(ctx->oC_With(withIndex++)))); + node->addElements(newNode); + break; + } else if (grammarName == "OC_WithContextE") { + newNode->addElements(any_cast(visitOC_With(ctx->oC_With(withIndex++)))); + node->addElements(newNode); + newNode = new ASTInternalNode(Const::SINGLE_QUERY); + } else if (grammarName == "OC_ReadingClauseContextE") { + newNode->addElements(any_cast(visitOC_ReadingClause(ctx->oC_ReadingClause(readIndex++)))); + } else if (grammarName == "OC_UpdatingClauseContextE") { + newNode->addElements(any_cast(visitOC_UpdatingClause(ctx->oC_UpdatingClause(updateIndex++)))); + } + } + } + + node->addElements(any_cast(visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()))); + + return static_cast(node); +} + + + +any ASTBuilder::visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) { + + if(ctx->oC_Create()) + { + return visitOC_Create(ctx->oC_Create()); + }else if(ctx->oC_Delete()) + { + return visitOC_Delete(ctx->oC_Delete()); + }else if(ctx->oC_Merge()) + { + return visitOC_Merge(ctx->oC_Merge()); + }else if(ctx->oC_Remove()) + { + return visitOC_Remove(ctx->oC_Remove()); + } + return visitOC_Set(ctx->oC_Set()); +} + +any ASTBuilder::visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) { + if(ctx->oC_Match()) + { + return visitOC_Match(ctx->oC_Match()); + }else if(ctx->oC_Unwind()) + { + return visitOC_Unwind(ctx->oC_Unwind()); + }else + { + return visitOC_InQueryCall(ctx->oC_InQueryCall()); + } +} + + +any ASTBuilder::visitOC_Match(CypherParser::OC_MatchContext *ctx) { + auto *node = new ASTInternalNode(Const::MATCH); + if(ctx->OPTIONAL()) + { + node->addElements(new ASTLeafNoValue(Const::OPTIONAL)); + } + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + if (ctx->oC_Where()) { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) { + auto *node = new ASTInternalNode(Const::UNWIND); + auto *nodeAS = new ASTInternalNode(Const::AS); + nodeAS->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + nodeAS->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(nodeAS); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Merge(CypherParser::OC_MergeContext *ctx) { + auto *node = new ASTInternalNode(Const::MERGE); + node->addElements(any_cast(visitOC_PatternPart(ctx->oC_PatternPart()))); + for(CypherParser::OC_MergeActionContext* element : ctx->oC_MergeAction()) + { + node->addElements(any_cast(visitOC_MergeAction(element))); + } + + return static_cast(node); +} + + +any ASTBuilder::visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) { + if(ctx->CREATE()) + { + auto *node = new ASTInternalNode(Const::ON_CREATE); + node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); + return static_cast(node); + } + auto *node = new ASTInternalNode(Const::ON_MATCH); + node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Create(CypherParser::OC_CreateContext *ctx) { + auto *node = new ASTInternalNode(Const::CREATE); + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + return static_cast(node); +} + + + +any ASTBuilder::visitOC_Set(CypherParser::OC_SetContext *ctx) { + if(ctx->oC_SetItem().size()>1) + { + auto *node = new ASTInternalNode(Const::MULTIPLE_SET); + for(CypherParser::OC_SetItemContext* element: ctx->oC_SetItem()) + { + node->addElements(any_cast(visitOC_SetItem(element))); + } + return static_cast(node); + } + return visitOC_SetItem(ctx->oC_SetItem()[0]); +} + + +any ASTBuilder::visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) { + if(ctx->oC_PropertyExpression()) + { + auto *node = new ASTInternalNode(Const::SET); + node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } else + { + if(ctx->getText().find("+=") != std::string::npos) + { + auto *node = new ASTInternalNode(Const::SET_PLUS_EQAL); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + }else if (ctx->getText().find("=") != std::string::npos) + { + auto *node = new ASTInternalNode(Const::SET_EUAL); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + auto *node = new ASTInternalNode(Const::SET); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_Delete(CypherParser::OC_DeleteContext *ctx) { + auto *deleteNode = new ASTInternalNode(Const::DELETE); + for(CypherParser::OC_ExpressionContext* element : ctx->oC_Expression()) + { + deleteNode->addElements(any_cast(visitOC_Expression(element))); + } + if(ctx->DETACH()) + { + auto *node = new ASTInternalNode(Const::DETACH); + node->addElements(deleteNode); + return static_cast(node); + } + return static_cast(deleteNode); +} + + +any ASTBuilder::visitOC_Remove(CypherParser::OC_RemoveContext *ctx) { + if(ctx->oC_RemoveItem().size()>1) + { + auto *node = new ASTInternalNode(Const::REMOVE_LIST); + for(CypherParser::OC_RemoveItemContext* element : ctx->oC_RemoveItem()) + { + node->addElements(any_cast(visitOC_RemoveItem(element))); + } + return static_cast(node); + } + + return visitOC_RemoveItem(ctx->oC_RemoveItem()[0]); +} + + + +any ASTBuilder::visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) { + auto *node = new ASTInternalNode(Const::REMOVE); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + return static_cast(node); + } + node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) { + auto *node = new ASTInternalNode(Const::CALL); + node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); + + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) { + if(ctx->oC_ExplicitProcedureInvocation()) + { + auto *node = new ASTInternalNode(Const::CALL); + node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + }else if(ctx->getText().find('*') != std::string::npos) + { + auto *star = new ASTLeafNoValue(Const::STAR); + node->addElements(star); + } + return static_cast(node); + } + + auto *node = new ASTInternalNode(Const::CALL); + node->addElements(any_cast(visitOC_ImplicitProcedureInvocation(ctx->oC_ImplicitProcedureInvocation()))); + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + }else if(ctx->getText().find('*') != std::string::npos) + { + auto *star = new ASTLeafNoValue(Const::STAR); + node->addElements(star); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) { + + auto *node = new ASTInternalNode(Const::YIELD_ITEMS); + for(CypherParser::OC_YieldItemContext* element : ctx->oC_YieldItem()) + { + node->addElements(any_cast(visitOC_YieldItem(element))); + } + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) { + auto *node = new ASTInternalNode(Const::YIELD); + if(ctx->oC_ProcedureResultField()) + { + auto *as = new ASTInternalNode(Const::AS); + as->addElements(any_cast(visitOC_ProcedureResultField(ctx->oC_ProcedureResultField()))); + as->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(as); + return static_cast(node); + } + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_With(CypherParser::OC_WithContext *ctx) { + auto *node = new ASTInternalNode(Const::WITH); + node->addElements(any_cast(visitOC_ProjectionBody(ctx->oC_ProjectionBody()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Return(CypherParser::OC_ReturnContext *ctx) { + return visitOC_ProjectionBody(ctx->oC_ProjectionBody()); +} + + +any ASTBuilder::visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) { + auto *node = new ASTInternalNode(Const::RETURN); + if(ctx->DISTINCT()) + { + auto *distinct = new ASTInternalNode(Const::DISTINCT); + distinct->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); + node->addElements(distinct); + }else + { + node->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); + } + if(ctx->oC_Order()) + { + node->addElements(any_cast(visitOC_Order(ctx->oC_Order()))); + } + if(ctx->oC_Skip()) + { + node->addElements(any_cast(visitOC_Skip(ctx->oC_Skip()))); + } + if(ctx->oC_Limit()) + { + node->addElements(any_cast(visitOC_Limit(ctx->oC_Limit()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) { + auto *node = new ASTInternalNode(Const::RETURN_BODY); + if(ctx->children[0]->getText() == "*") + { + node->addElements(new ASTLeafNoValue(Const::STAR)); + } + for(CypherParser::OC_ProjectionItemContext* element : ctx->oC_ProjectionItem()) + { + node->addElements(any_cast(visitOC_ProjectionItem(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) { + if(ctx->oC_Variable()) + { + auto *node = new ASTInternalNode(Const::AS); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + return static_cast(node); + } + return visitOC_Expression(ctx->oC_Expression()); +} + + +any ASTBuilder::visitOC_Order(CypherParser::OC_OrderContext *ctx) { + auto *node = new ASTInternalNode(Const::ORDERED_BY); + for(CypherParser::OC_SortItemContext* element : ctx->oC_SortItem()) + { + node->addElements(any_cast(visitOC_SortItem(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Skip(CypherParser::OC_SkipContext *ctx) { + auto *node = new ASTInternalNode(Const::SKIP); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Limit(CypherParser::OC_LimitContext *ctx) { + auto *node = new ASTInternalNode(Const::LIMIT); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + + +any ASTBuilder::visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) { + if(ctx->ASC() or ctx->ASCENDING()) + { + auto *node = new ASTInternalNode(Const::ASC); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode(Const::DESC); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_Where(CypherParser::OC_WhereContext *ctx) { + auto *node = new ASTInternalNode(Const::WHERE); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Pattern(CypherParser::OC_PatternContext *ctx) { + auto *node = new ASTInternalNode(Const::PATTERN); + for(CypherParser::OC_PatternPartContext* element : ctx->oC_PatternPart()) + { + node->addElements(any_cast(visitOC_PatternPart(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) { + if(ctx->oC_Variable()) + { + auto *node = new ASTInternalNode(Const::EQUAL); + + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()))); + + return static_cast(node); + } + return visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()); +} + + +any ASTBuilder::visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) { + return visitOC_PatternElement(ctx->oC_PatternElement()); +} + + +any ASTBuilder::visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) { + if(ctx->oC_PatternElement()) + { + return visitOC_PatternElement(ctx->oC_PatternElement()); + } + + if(!ctx->oC_PatternElementChain().empty()) + { + auto *node = new ASTInternalNode(Const::PATTERN_ELEMENTS); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) + { + node->addElements(any_cast(visitOC_PatternElementChain(element))); + } + return static_cast(node); + } + return visitOC_NodePattern(ctx->oC_NodePattern()); +} + +//finsihed +any ASTBuilder::visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) { + auto *node = new ASTInternalNode(Const::PATTERN_ELEMENTS); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) + { + node->addElements(any_cast(visitOC_PatternElementChain(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) { + auto *node = new ASTInternalNode(Const::NODE_PATTERN); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + } + if(ctx->oC_NodeLabels()) + { + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + } + if(ctx->oC_Properties()) + { + node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) { + auto *node = new ASTInternalNode(Const::PATTERN_ELEMENT_CHAIN); + node->addElements(any_cast(visitOC_RelationshipPattern(ctx->oC_RelationshipPattern()))); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) { + auto *node = new ASTInternalNode(Const::RELATIONSHIP_PATTTERN); + if(ctx->oC_LeftArrowHead() && !ctx->oC_RightArrowHead()) + { + node->addElements(any_cast(visitOC_LeftArrowHead(ctx->oC_LeftArrowHead()))); + }else if(!ctx->oC_LeftArrowHead() && ctx->oC_RightArrowHead()) + { + node->addElements(any_cast(visitOC_RightArrowHead(ctx->oC_RightArrowHead()))); + }else + { + node->addElements(new ASTLeafNoValue(Const::UNIDIRECTION_ARROW)); + } + if(ctx->oC_RelationshipDetail()) + { + node->addElements(any_cast(visitOC_RelationshipDetail(ctx->oC_RelationshipDetail()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) { + auto *node = new ASTInternalNode(Const::RELATIONSHIP_DETAILS); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + } + if(ctx->oC_RelationshipTypes()) + { + node->addElements(any_cast(visitOC_RelationshipTypes(ctx->oC_RelationshipTypes()))); + } + if(ctx->oC_RangeLiteral()) + { + node->addElements(any_cast(visitOC_RangeLiteral(ctx->oC_RangeLiteral()))); + } + if(ctx->oC_Properties()) + { + node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); + } + return static_cast(node); ; +} + + +any ASTBuilder::visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) { + if(ctx->oC_Parameter()) + { + return visitOC_Parameter(ctx->oC_Parameter()); + } + return visitOC_MapLiteral(ctx->oC_MapLiteral()); +} + + +any ASTBuilder::visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) { + + if(ctx->oC_RelTypeName().size()>1) + { + auto *node = new ASTInternalNode(Const::RELATIONSHIP_TYPES); + for(CypherParser::OC_RelTypeNameContext* element : ctx->oC_RelTypeName()) + { + node->addElements(any_cast(visitOC_RelTypeName(element))); + } + return static_cast(node); + } + return visitOC_RelTypeName(ctx->oC_RelTypeName()[0]); +} + + +any ASTBuilder::visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) { + if(ctx->oC_NodeLabel().size()>1) + { + auto *node = new ASTInternalNode(Const::NODE_LABELS); + for(CypherParser::OC_NodeLabelContext* element : ctx->oC_NodeLabel()) + { + node->addElements(any_cast(visitOC_NodeLabel(element))); + } + return static_cast(node); + } + return visitOC_NodeLabel(ctx->oC_NodeLabel()[0]); +} + + +any ASTBuilder::visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) { + auto *node = new ASTInternalNode(Const::NODE_LABEL); + node->addElements(any_cast(visitOC_LabelName(ctx->oC_LabelName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) { + auto *node = new ASTInternalNode(Const::RANGE); + if(ctx->oC_IntegerLiteral().size()>1) + { + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[1]))); + return static_cast(node); + } + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) { + return visitOC_SchemaName(ctx->oC_SchemaName()); +} + + +any ASTBuilder::visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) { + return visitOC_SchemaName(ctx->oC_SchemaName()); +} + + +any ASTBuilder::visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) { + auto *node = new ASTInternalNode(Const::PROPERTY); + node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); + for(CypherParser::OC_PropertyLookupContext* element : ctx->oC_PropertyLookup()) + { + node->addElements(any_cast(visitOC_PropertyLookup(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) { + return visitOC_OrExpression(ctx->oC_OrExpression()); +} + + +any ASTBuilder::visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) { + if(ctx->oC_XorExpression().size()>1) + { + auto *node = new ASTInternalNode(Const::OR); + for(CypherParser::OC_XorExpressionContext* element : ctx->oC_XorExpression()) + { + node->addElements(any_cast(visitOC_XorExpression(element))); + } + return static_cast(node); + } + return visitOC_XorExpression(ctx->oC_XorExpression()[0]); +} + + +any ASTBuilder::visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) { + if(ctx->oC_AndExpression().size()>1) + { + auto *node = new ASTInternalNode(Const::XOR); + for(CypherParser::OC_AndExpressionContext* element : ctx->oC_AndExpression()) + { + node->addElements(any_cast(visitOC_AndExpression(element))); + } + } + return visitOC_AndExpression(ctx->oC_AndExpression()[0]); +} + + +any ASTBuilder::visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) { + if(ctx->oC_NotExpression().size()>1) + { + auto *node = new ASTInternalNode(Const::AND); + for(CypherParser::OC_NotExpressionContext* element : ctx->oC_NotExpression()) + { + node->addElements(any_cast(visitOC_NotExpression(element))); + } + return static_cast(node); + } + return visitOC_NotExpression(ctx->oC_NotExpression()[0]); +} + + +any ASTBuilder::visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) { + if(!ctx->NOT().empty()) + { + if(ctx->NOT().size() % 2 != 0) + { + auto *node = new ASTInternalNode(Const::NOT); + node->addElements(any_cast(visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()))); + return static_cast(node); + } + } + return visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()); +} + + + +any ASTBuilder::visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) { + if(!ctx->oC_PartialComparisonExpression().empty()) + { + auto *node = new ASTInternalNode(Const::COMPARISON); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + for(CypherParser::OC_PartialComparisonExpressionContext* element : ctx->oC_PartialComparisonExpression()) + { + node->addElements(any_cast(visitOC_PartialComparisonExpression(element))); + } + return static_cast(node); + } + return visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()); +} + + +any ASTBuilder::visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) { + if(ctx->getText().find(">") != string::npos) + { + auto *node = new ASTInternalNode(Const::GREATER_THAN); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("<>") != string::npos) + { + auto *node = new ASTInternalNode(Const::GREATER_THAN_LOWER_THAN); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("=") != string::npos) + { + auto *node = new ASTInternalNode(Const::DOUBLE_EQUAL); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("<") != string::npos) + { + auto *node = new ASTInternalNode(Const::LOWER_THAN); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find(">=") != string::npos) + { + auto *node = new ASTInternalNode(Const::GREATER_THAN_OR_EQUAL); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode(Const::LOWER_THAN_OR_EQUAL); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) { + auto *node = new ASTInternalNode(Const::PREDICATE_EXPRESSIONS); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + if(!ctx->oC_StringPredicateExpression().empty()) + { + auto *strPredicate = new ASTInternalNode(Const::STRING_PREDICATES); + for(CypherParser::OC_StringPredicateExpressionContext* element: ctx->oC_StringPredicateExpression()) + { + strPredicate->addElements(any_cast(visitOC_StringPredicateExpression(element))); + } + node->addElements(strPredicate); + } + if(!ctx->oC_ListPredicateExpression().empty()) + { + auto *listPredicate = new ASTInternalNode(Const::LIST_PREDICATES); + for(CypherParser::OC_ListPredicateExpressionContext* element: ctx->oC_ListPredicateExpression()) + { + listPredicate->addElements(any_cast(visitOC_ListPredicateExpression(element))); + } + node->addElements(listPredicate); + } + if(!ctx->oC_NullPredicateExpression().empty()) + { + auto *nullPredicate = new ASTInternalNode(Const::NULL_PREDICATES); + for(CypherParser::OC_NullPredicateExpressionContext* element: ctx->oC_NullPredicateExpression()) + { + nullPredicate->addElements(any_cast(visitOC_NullPredicateExpression(element))); + } + node->addElements(nullPredicate); + } + if(node->elements.size()>1) + { + return static_cast(node); + }else + { + return visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()); + } +} + + +any ASTBuilder::visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) { + if(ctx->STARTS()) + { + auto *node = new ASTInternalNode(Const::STARTS_WITH); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + }else if(ctx->ENDS()) + { + auto *node = new ASTInternalNode(Const::ENDS_WITH); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode(Const::CONTAINS); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + } +} + + + +any ASTBuilder::visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) { + auto *node = new ASTInternalNode(Const::IN); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) { + if(ctx->NOT()) + { + auto *node = new ASTLeafNoValue(Const::IS_NOT_NULL); + return static_cast(node); + } + auto *node = new ASTLeafNoValue(Const::IS_NULL); + return static_cast(node); +} + + +any ASTBuilder::visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) { + if(ctx->oC_MultiplyDivideModuloExpression().size()>1) + { + int multIndex =1; + auto *node = new ASTInternalNode(Const::ADD_OR_SUBSTRACT); + node->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "+") + { + auto *plus = new ASTInternalNode(Const::PLUS); + plus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); + node->addElements(plus); + }else if(ctx->children[i]->getText() == "-") + { + auto *minus = new ASTInternalNode(Const::MINUS); + minus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); + node->addElements(minus); + } + } + return static_cast(node); + } + return visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)); +} + + +any ASTBuilder::visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) { + if(ctx->oC_PowerOfExpression().size()>1) + { + int powIndex = 1; + auto *node = new ASTInternalNode(Const::MULTIPLY_DIVID_MODULO); + node->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "*") + { + auto *plus = new ASTInternalNode(Const::STAR); + plus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); + node->addElements(plus); + }else if(ctx->children[i]->getText() == "/") + { + auto *minus = new ASTInternalNode(Const::DIVIDE); + minus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); + node->addElements(minus); + } + } + return static_cast(node); + } + + return visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)); +} + + +any ASTBuilder::visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) { + if(ctx->oC_UnaryAddOrSubtractExpression().size()>1) + { + int unaryIndex = 1; + auto *node = new ASTInternalNode(Const::POWER_OF); + node->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "^") + { + auto *plus = new ASTInternalNode(Const::POWER); + plus->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(unaryIndex++)))); + node->addElements(plus); + } + } + return static_cast(node); + } + return visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)); +} + + + +any ASTBuilder::visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) { + if(ctx->children[0]->getText() == "+") + { + auto *node = new ASTInternalNode(Const::UNARY_PLUS); + node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); + return static_cast(node); + }else if(ctx->children[0]->getText() == "-") + { + auto *node = new ASTInternalNode(Const::UNARY_MINUS); + node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); + return static_cast(node); + }else + { + return visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()); + } +} + + +any ASTBuilder::visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) { + auto *node = new ASTInternalNode(Const::NON_ARITHMETIC_OPERATOR); + if(!ctx->oC_ListOperatorExpression().empty() | !ctx->oC_PropertyLookup().empty()) + { + int i = 0; + int j = 0; + for(auto *child : ctx->children) + { + std::string typeName = typeid(*child).name(); + if(typeName.substr(17) == "OC_AtomContextE") + { + node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); + }else if(typeName.substr(17) == "OC_PropertyLookupContextE") + { + node->addElements(any_cast(visitOC_PropertyLookup(ctx->oC_PropertyLookup(i++)))); + }else if(typeName.substr(17) == "OC_ListOperatorExpressionContextE") + { + node->addElements(any_cast(visitOC_ListOperatorExpression(ctx->oC_ListOperatorExpression(j++)))); + }else + { + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + } + } + return static_cast(node); + }else if(ctx->oC_NodeLabels()) + { + node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + return static_cast(node); + } + return visitOC_Atom(ctx->oC_Atom()); +} + + +any ASTBuilder::visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) { + if(ctx->oC_Expression().size() == 2) + { + auto *node = new ASTInternalNode(Const::LIST_INDEX_RANGE); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + return static_cast(node); + } + auto *node = new ASTInternalNode(Const::LIST_INDEX); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) { + auto *node = new ASTInternalNode(Const::PROPERTY_LOOKUP); + node->addElements(any_cast(visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Atom(CypherParser::OC_AtomContext *ctx) { + if(ctx->oC_Literal()) + { + return visitOC_Literal(ctx->oC_Literal()); + }else if(ctx->oC_Parameter()) + { + return visitOC_Parameter(ctx->oC_Parameter()); + }else if(ctx->oC_Quantifier()) + { + return visitOC_Quantifier(ctx->oC_Quantifier()); + }else if(ctx->oC_Variable()) + { + return visitOC_Variable(ctx->oC_Variable()); + }else if(ctx->oC_CaseExpression()) + { + return visitOC_CaseExpression(ctx->oC_CaseExpression()); + }else if(ctx->oC_ExistentialSubquery()) + { + return visitOC_ExistentialSubquery(ctx->oC_ExistentialSubquery()); + }else if(ctx->oC_FunctionInvocation()) + { + return visitOC_FunctionInvocation(ctx->oC_FunctionInvocation()); + }else if(ctx->oC_ListComprehension()) + { + return visitOC_ListComprehension(ctx->oC_ListComprehension()); + }else if(ctx->oC_ParenthesizedExpression()) + { + return visitOC_ParenthesizedExpression(ctx->oC_ParenthesizedExpression()); + }else if(ctx->oC_PatternComprehension()) + { + return visitOC_PatternComprehension(ctx->oC_PatternComprehension()); + }else if(ctx->oC_PatternPredicate()) + { + return visitOC_PatternPredicate(ctx->oC_PatternPredicate()); + }else + { + auto *node = new ASTLeafValue(Const::COUNT, "*"); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) { + auto *caseNode = new ASTInternalNode(Const::CASE_PATTERN); + int caseAlt = 0; + for(int i = 0; ichildren.size(); i++) + { + string text = ctx->children[i]->getText(); + std::transform(text.begin(), text.end(), text.begin(), ::toupper); + string type; + if(i+2 < ctx->children.size()) + { + type = typeid(*ctx->children[i+2]).name(); + } + if(text == "CASE" && type.substr(17) == "OC_ExpressionContextE") + { + auto *node = new ASTInternalNode(Const::CASE_EXPRESSION); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + caseNode->addElements(node); + }else if(text == "ELSE" && ctx->oC_Expression().size()>1) + { + auto *node = new ASTInternalNode(Const::ELSE_EXPRESSION); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + caseNode->addElements(node); + }else if(text == "ELSE") + { + auto *node = new ASTInternalNode(Const::ELSE_EXPRESSION); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + caseNode->addElements(node); + }else if(text.find("WHEN") != string::npos) + { + caseNode->addElements(any_cast(visitOC_CaseAlternative(ctx->oC_CaseAlternative(caseAlt++)))); + } + } + return static_cast(caseNode); +} + + +any ASTBuilder::visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) { + auto *node = new ASTInternalNode(Const::CASE); + + auto *when = new ASTInternalNode(Const::WHEN); + when->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + + auto *then = new ASTInternalNode(Const::THEN); + then->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + + node->addElements(when); + node->addElements(then); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) { + auto *node = new ASTInternalNode(Const::LIST_COMPREHENSION); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + if(ctx->getText().find('|') != string::npos) + { + auto *result = new ASTInternalNode(Const::FILTER_RESULT); + result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(result); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) { + auto *node = new ASTInternalNode(Const::PATTERN_COMPREHENSION); + if(ctx->oC_Variable()) + { + auto *equal = new ASTInternalNode(Const::EQUAL); + equal->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + equal->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); + node->addElements(equal); + }else + { + node->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); + } + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + auto *result = new ASTInternalNode(Const::FILTER_RESULT); + result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(result); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) { + if(ctx->ALL()) + { + auto *node = new ASTInternalNode(Const::ALL); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else if(ctx->ANY()) + { + auto *node = new ASTInternalNode(Const::ANY); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else if(ctx->NONE()) + { + auto *node = new ASTInternalNode(Const::NONE); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode(Const::SINGLE); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) { + auto *node = new ASTInternalNode(Const::FILTER_EXPRESSION); + node->addElements(any_cast(visitOC_IdInColl(ctx->oC_IdInColl()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) { + return visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()); +} + + +any ASTBuilder::visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) { + return visitOC_Expression(ctx->oC_Expression()); +} + + +any ASTBuilder::visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) { + auto *node = new ASTInternalNode(Const::LIST_ITERATE); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) { + auto *node = new ASTInternalNode(Const::FUNCTION_BODY); + node->addElements(any_cast(visitOC_FunctionName(ctx->oC_FunctionName()))); + + auto *aug = new ASTInternalNode(Const::ARGUMENTS); + if(ctx->DISTINCT()) + { + auto *distinct = new ASTInternalNode(Const::DISTINCT); + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + distinct->addElements(any_cast(visitOC_Expression(elements))); + } + aug->addElements(distinct); + node->addElements(aug); + return static_cast(node); + } + + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + aug->addElements(any_cast(visitOC_Expression(elements))); + } + if(!aug->elements.empty()) + { + node->addElements(aug); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) { + auto *node = new ASTInternalNode(Const::FUNCTION); + node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); + auto *name = new ASTLeafValue(Const::FUNCTION_NAME, any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + node->addElements(name); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) { + auto *node = new ASTInternalNode(Const::EXISTS); + if(ctx->oC_RegularQuery()) + { + node->addElements(any_cast(visitOC_RegularQuery(ctx->oC_RegularQuery()))); + return static_cast(node); + }else + { + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) { + auto *node = new ASTInternalNode(Const::EXPLICIT_PROCEDURE); + node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); + if(ctx->oC_Expression().size()>1) + { + auto *arg = new ASTInternalNode(Const::ARGUMENTS); + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + arg->addElements(any_cast(visitOC_Expression(elements))); + } + node->addElements(arg); + return static_cast(node); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) { + auto *node = new ASTInternalNode(Const::IMPLICIT_PROCEDURE); + node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) { + auto *node = new ASTLeafValue(Const::PROCEDURE_RESULT, any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) { + auto *node = new ASTInternalNode(Const::PROCEDURE); + node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); + auto *name = new ASTLeafValue(Const::PROCEDURE_NAME, any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + node->addElements(name); + return static_cast(node); +} + + + +any ASTBuilder::visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) { + auto *node = new ASTInternalNode(Const::NAMESPACE); + for(CypherParser::OC_SymbolicNameContext* element : ctx->oC_SymbolicName()) + { + auto *name = new ASTLeafNoValue(any_cast(visitOC_SymbolicName(element))); + node->addElements(name); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Variable(CypherParser::OC_VariableContext *ctx) { + auto *node = new ASTLeafValue(Const::VARIABLE, any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Literal(CypherParser::OC_LiteralContext *ctx) { + if(ctx->oC_BooleanLiteral()) + { + return visitOC_BooleanLiteral(ctx->oC_BooleanLiteral()); + }else if(ctx->oC_ListLiteral()) + { + return visitOC_ListLiteral(ctx->oC_ListLiteral()); + }else if(ctx->oC_MapLiteral()) + { + return visitOC_MapLiteral(ctx->oC_MapLiteral()); + }else if(ctx->oC_NumberLiteral()) + { + return visitOC_NumberLiteral(ctx->oC_NumberLiteral()); + }else if(ctx->NULL_()) + { + auto *node = new ASTLeafNoValue(Const::NULL_STRING); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue(Const::STRING, ctx->getText()); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) { + if(ctx->TRUE()) + { + auto *node = new ASTLeafValue(Const::BOOLEAN, "TRUE"); + return static_cast(node); + } else + { + auto *node = new ASTLeafValue(Const::BOOLEAN, "FALSE"); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) { + if(ctx->oC_DoubleLiteral()) + { + return visitOC_DoubleLiteral(ctx->oC_DoubleLiteral()); + } + return visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()); +} + + +any ASTBuilder::visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) { + if(ctx->DecimalInteger()) + { + auto *node = new ASTLeafValue(Const::DECIMAL, ctx->getText()); + return static_cast(node); + } else if(ctx->HexInteger()) + { + auto *node = new ASTLeafValue(Const::HEX, ctx->getText()); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue(Const::OCTAL, ctx->getText()); + return static_cast(node); + } + +} + + +any ASTBuilder::visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) { + if(ctx->ExponentDecimalReal()) + { + auto *node = new ASTLeafValue(Const::EXP_DECIMAL, ctx->getText()); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue(Const::REGULAR_DECIMAL, ctx->getText()); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) { + auto *node = new ASTInternalNode(Const::LIST); + for(CypherParser::OC_ExpressionContext* element: ctx->oC_Expression()) + { + node->addElements(any_cast(visitOC_Expression(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) { + auto *node = new ASTInternalNode(Const::PROPERTIES_MAP); + for(int i=0; ioC_PropertyKeyName().size();i++) + { + auto *propNode = new ASTInternalNode(Const::PROPERTY); + propNode->addElements(any_cast(visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()[i]))); + propNode->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()[i]))); + node->addElements(propNode); + } + + return static_cast(node); +} + + +any ASTBuilder::visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) { + return visitOC_SchemaName(ctx->oC_SchemaName()); +} + + +any ASTBuilder::visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) { + if(ctx->oC_SymbolicName()) + { + auto *node = new ASTLeafValue(Const::PARAMETER, any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue(Const::PARAMETER, ctx->getText()); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) { + if(ctx->oC_ReservedWord()) + { + return visitOC_ReservedWord(ctx->oC_ReservedWord()); + } + auto *node = new ASTLeafValue(Const::SYMBOLIC_WORD,any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) { + auto *node = new ASTLeafValue(Const::RESERVED_WORD, ctx->getText()); + return static_cast(node); +} + + +any ASTBuilder::visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) { + return ctx->getText(); +} + + +any ASTBuilder::visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) { + return static_cast(new ASTLeafNoValue(Const::LEFT_ARRROW)); +} + + +any ASTBuilder::visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) { + return static_cast(new ASTLeafNoValue(Const::RIGHT_ARROW));; +} diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.h b/src/query/processor/cypher/astbuilder/ASTBuilder.h new file mode 100644 index 00000000..a745d20c --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.h @@ -0,0 +1,232 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include +#include "/home/ubuntu/software/antlr/CypherBaseVisitor.h" +#ifndef AST_BUILDER_H +#define AST_BUILDER_H + +using namespace std; + +class ASTBuilder : public CypherBaseVisitor { +public: + + std::any visitOC_Cypher(CypherParser::OC_CypherContext *ctx) override; + + std::any visitOC_Statement(CypherParser::OC_StatementContext *ctx) override; + + std::any visitOC_Query(CypherParser::OC_QueryContext *ctx) override; + + std::any visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) override ; + + std::any visitOC_Union(CypherParser::OC_UnionContext *ctx) override; + + std::any visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) override; + + std::any visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) override; + + std::any visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) override; + + std::any visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) override ; + + std::any visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) override ; + + std::any visitOC_Match(CypherParser::OC_MatchContext *ctx) override ; + + std::any visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) override ; + + std::any visitOC_Merge(CypherParser::OC_MergeContext *ctx) override ; + + std::any visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) override ; + + std::any visitOC_Create(CypherParser::OC_CreateContext *ctx) override ; + + std::any visitOC_Set(CypherParser::OC_SetContext *ctx) override ; + + std::any visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) override; + + std::any visitOC_Delete(CypherParser::OC_DeleteContext *ctx) override ; + + std::any visitOC_Remove(CypherParser::OC_RemoveContext *ctx) override ; + + std::any visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) override ; + + std::any visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) override ; + + std::any visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) override; + + std::any visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) override ; + + std::any visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) override ; + + std::any visitOC_With(CypherParser::OC_WithContext *ctx) override ; + + std::any visitOC_Return(CypherParser::OC_ReturnContext *ctx) override ; + + std::any visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) override ; + + std::any visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) override ; + + std::any visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) override ; + + std::any visitOC_Order(CypherParser::OC_OrderContext *ctx) override ; + + std::any visitOC_Skip(CypherParser::OC_SkipContext *ctx) override ; + + std::any visitOC_Limit(CypherParser::OC_LimitContext *ctx) override ; + + std::any visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) override ; + + std::any visitOC_Where(CypherParser::OC_WhereContext *ctx) override ; + + std::any visitOC_Pattern(CypherParser::OC_PatternContext *ctx) override ; + + std::any visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) override ; + + std::any visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) override ; + + std::any visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) override ; + + std::any visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) override ; + + std::any visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) override ; + + std::any visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) override ; + + std::any visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) override ; + + std::any visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) override ; + + std::any visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) override ; + + std::any visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) override ; + + + std::any visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) override ; + + std::any visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) override ; + + std::any visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) override ; + + std::any visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) override ; + + std::any visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) override ; + + std::any visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) override ; + + std::any visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) override ; + + std::any visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) override ; + + std::any visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) override ; + + std::any visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) override ; + + std::any visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) override ; + + std::any visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) override ; + + std::any visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) override ; + + + std::any visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) override ; + + std::any visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) override ; + + std::any visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) override ; + + std::any visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) override ; + + std::any visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) override ; + + std::any visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) override ; + + std::any visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) override ; + + std::any visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) override ; + + std::any visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) override ; + + std::any visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) override ; + + std::any visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) override ; + + std::any visitOC_Atom(CypherParser::OC_AtomContext *ctx) override ; + + std::any visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) override ; + + std::any visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) override ; + + std::any visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) override ; + + std::any visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) override ; + + std::any visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) override ; + + std::any visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) override ; + + std::any visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) override ; + + std::any visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) override ; + + std::any visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) override ; + + std::any visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) override ; + + std::any visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) override ; + + std::any visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) override ; + + std::any visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) override ; + + std::any visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) override ; + + std::any visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) override ; + + std::any visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) override ; + + std::any visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) override ; + + std::any visitOC_Variable(CypherParser::OC_VariableContext *ctx) override ; + + std::any visitOC_Literal(CypherParser::OC_LiteralContext *ctx) override ; + + std::any visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) override ; + + std::any visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) override ; + + std::any visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) override ; + + std::any visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) override ; + + std::any visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) override ; + + std::any visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) override ; + + std::any visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) override ; + + std::any visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) override ; + + std::any visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) override ; + + std::any visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) override ; + + std::any visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) override ; + + std::any visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) override ; + + std::any visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) override ; + +}; + +#endif //AST_BUILDER_H diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp new file mode 100644 index 00000000..aa614e66 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp @@ -0,0 +1,19 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTInternalNode.h" + +void ASTInternalNode::addElements(ASTNode* element) +{ + elements.push_back(element); +} \ No newline at end of file diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.h b/src/query/processor/cypher/astbuilder/ASTInternalNode.h new file mode 100644 index 00000000..f43eb942 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.h @@ -0,0 +1,32 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTNode.h" + +#ifndef ASTINTERNALNODE_H +#define ASTINTERNALNODE_H + +using namespace std; + +class ASTInternalNode : public ASTNode{ + + public: + ASTInternalNode(string nodeType) + { + this->nodeType = nodeType; + } + + void addElements(ASTNode* element) ; +}; + +#endif //ASTINTERNALNODE_H diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp new file mode 100644 index 00000000..973a01ac --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp @@ -0,0 +1,14 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTLeafNoValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h new file mode 100644 index 00000000..64fa4505 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h @@ -0,0 +1,27 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTNode.h" +#ifndef ASTLEAFNOVALUE_H +#define ASTLEAFNOVALUE_H + +class ASTLeafNoValue : public ASTNode { +public: + ASTLeafNoValue(const std::string& name) + { + this->nodeType = name; + }; + +}; + +#endif //ASTLEAFNOVALUE_H diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp new file mode 100644 index 00000000..c058c74e --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp @@ -0,0 +1,14 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTLeafValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.h b/src/query/processor/cypher/astbuilder/ASTLeafValue.h new file mode 100644 index 00000000..5fd854af --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.h @@ -0,0 +1,29 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTNode.h" +#ifndef ASTLEAFVALUE_H +#define ASTLEAFVALUE_H + +class ASTLeafValue : public ASTNode { +public: + + ASTLeafValue(const std::string& name, const std::string& value) + { + this->nodeType = name; + this->value = value; + }; + +}; + +#endif //ASTLEAFVALUE_H diff --git a/src/query/processor/cypher/astbuilder/ASTNode.cpp b/src/query/processor/cypher/astbuilder/ASTNode.cpp new file mode 100644 index 00000000..29a447e9 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTNode.cpp @@ -0,0 +1,38 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ASTNode.h" +#include +#include +#include + + +using namespace std; + +string ASTNode::print(int depth, string prefix, bool isLast) const +{ + stringstream ss; + + ss << prefix; + ss << (isLast ? "└───" : "├──"); + ss << nodeType << ": " << value << "\n"; + + string result = ss.str(); + prefix += (isLast ? " " : "│ "); + + for (size_t i = 0; i < elements.size(); ++i) { + result += elements[i]->print(depth + 1, prefix, i == elements.size() - 1); + } + + return result; +} diff --git a/src/query/processor/cypher/astbuilder/ASTNode.h b/src/query/processor/cypher/astbuilder/ASTNode.h new file mode 100644 index 00000000..9ca48420 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTNode.h @@ -0,0 +1,37 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include +#include + + +#ifndef AST_NODE_H +#define AST_NODE_H + +using namespace std; + +class ASTNode { + public: + string nodeType; + vector elements; + string value; + virtual ~ASTNode() = default; + + string print(int depth = 0, string prefix = "", bool isLast = true) const; + +}; + + + + +#endif diff --git a/src/query/processor/cypher/semanticanalyzer/Scope.cpp b/src/query/processor/cypher/semanticanalyzer/Scope.cpp new file mode 100644 index 00000000..89a84459 --- /dev/null +++ b/src/query/processor/cypher/semanticanalyzer/Scope.cpp @@ -0,0 +1,46 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "Scope.h" +#include +using namespace std; +Scope::Scope(Scope* parent) +{ + parentScope = parent; + symbolTable = new unordered_map(); +} + +void Scope::addSymbol(const string& symbolName, const std::string& symbolType) { + pair x = pair(symbolName,symbolType); + symbolTable->insert(x); +} + +void Scope::clearTable() +{ + symbolTable->clear(); +} + +string Scope::getType(const string& symbolName) { + return symbolTable->at(symbolName); +} + +optional Scope::lookup(const std::string& symbolName) const { + + if (symbolTable->find(symbolName) != symbolTable->end()) { + return symbolTable->at(symbolName); + } else if (parentScope) { + return parentScope->lookup(symbolName); + } else { + return std::nullopt; + } +} diff --git a/src/query/processor/cypher/semanticanalyzer/Scope.h b/src/query/processor/cypher/semanticanalyzer/Scope.h new file mode 100644 index 00000000..5dd95a1b --- /dev/null +++ b/src/query/processor/cypher/semanticanalyzer/Scope.h @@ -0,0 +1,34 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + + +#ifndef SCOPE_H +#define SCOPE_H + +#include +#include +#include + +class Scope { +public: + Scope(Scope* parent = nullptr); + void addSymbol(const std::string& symbolName, const std::string& symbolType); + void clearTable(); + std::string getType(const std::string& symbolName); + std::optional lookup(const std::string& symbolName) const; + std::unordered_map *symbolTable; +private: + Scope* parentScope; +}; + +#endif // SCOPE_H diff --git a/src/query/processor/cypher/semanticanalyzer/ScopeManager.cpp b/src/query/processor/cypher/semanticanalyzer/ScopeManager.cpp new file mode 100644 index 00000000..65506d55 --- /dev/null +++ b/src/query/processor/cypher/semanticanalyzer/ScopeManager.cpp @@ -0,0 +1,66 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "ScopeManager.h" + +using namespace std; + +ScopeManager::ScopeManager() { + enterScope();// Initialize with a global scope +} + +void ScopeManager::enterScope() { + // Create a new scope and use shared_ptr to manage its memory + auto *newScope = new Scope(currentScope); + currentScope = newScope; + scopeStack.push(newScope); +} + +void ScopeManager::exitScope() { + if (!scopeStack.empty()) { + scopeStack.pop(); // Remove the current scope from the stack + + // Update currentScope to the new top of the stack or nullptr if empty + currentScope = scopeStack.empty() ? nullptr : scopeStack.top(); + } +} + +void ScopeManager::addSymbol(const string& symbolName, const string& symbolType) { + if (currentScope) { // Ensure currentScope is valid + currentScope->addSymbol(symbolName, symbolType); + } +} + +void ScopeManager::clearTable() +{ + if(currentScope) + { + currentScope->clearTable(); + } +} + +string ScopeManager::getType(const std::string& symbolName) +{ + if(currentScope) + { + return currentScope->getType(symbolName); + } + return nullptr; +} + +optional ScopeManager::lookup(const string& symbolName) const { + if (currentScope) { // Ensure currentScope is valid + return currentScope->lookup(symbolName); + } + return nullopt; +} diff --git a/src/query/processor/cypher/semanticanalyzer/ScopeManager.h b/src/query/processor/cypher/semanticanalyzer/ScopeManager.h new file mode 100644 index 00000000..2ec5b540 --- /dev/null +++ b/src/query/processor/cypher/semanticanalyzer/ScopeManager.h @@ -0,0 +1,38 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#ifndef SCOPE_MANAGER_H +#define SCOPE_MANAGER_H + +#include +#include +#include +#include "Scope.h" + +class ScopeManager { +public: + ScopeManager(); + + void enterScope(); + void exitScope(); + void addSymbol(const std::string& symbolName, const std::string& symbolType); + void clearTable(); + std::string getType(const std::string& symbolName); + std::optional lookup(const std::string& symbolName) const; + +private: + std::stack scopeStack; // Stack of smart pointers + Scope* currentScope = nullptr; // Current scope managed by smart pointer +}; + +#endif // SCOPE_MANAGER_H diff --git a/src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.cpp b/src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.cpp new file mode 100644 index 00000000..18419e1c --- /dev/null +++ b/src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.cpp @@ -0,0 +1,271 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include +#include "SemanticAnalyzer.h" +#include "ScopeManager.h" +#include "../../../../util/logger/Logger.h" +#include "../util/Const.h" + +using namespace std; + +// Constructor +SemanticAnalyzer::SemanticAnalyzer() { + // Initialize the scope manager with the global scope + scopeManager = new ScopeManager(); + temp = new unordered_map();// Enter global scope +} + +// Destructor +SemanticAnalyzer::~SemanticAnalyzer() { + // Ensure to exit all scopes upon destruction + scopeManager->exitScope(); +} + + +// Main method to analyze the AST +bool SemanticAnalyzer::analyze(ASTNode* root, bool canDefine, string type) { + if(root->nodeType == Const::VARIABLE && canDefine) + { + if(!checkVariableDeclarations(root, type)) + { + return false; + } + }else if(root->nodeType == Const::VARIABLE) + { + if(!checkVariableUsage(root, type)) + { + return false; + } + }else if (root->nodeType == Const::AS) + { + string ntype; + if (root->elements[0]->nodeType == Const::LIST || root->elements[0]->nodeType == Const::LIST_COMPREHENSION) + { + ntype = Const::LIST; + } + else if (root->elements[0]->nodeType == Const::PROPERTIES_MAP) + { + ntype = Const::MAP; + } + else + { + ntype = Const::ANY; + } + if(!analyze(root->elements[0])) + { + return false; + } + if(root->elements[1]->nodeType != Const::VARIABLE || !analyze(root->elements[1],true, ntype)) + { + return false; + } + }else if(root->nodeType == Const::YIELD) + { + if(root->elements[0]->nodeType == "AS" && !analyze(root->elements[0], false,Const::STRING)) + { + return false; + } + if(!analyze(root->elements[0],true, Const::STRING)) + { + return false; + } + }else if(root->nodeType == Const::EQUAL) + { + string ntype = root->nodeType == Const::PATTERN_ELEMENTS ? Const::PATH_PATTERN : Const::ANY; + if(!analyze(root->elements[0],true, ntype)) + { + return false; + } + if(!analyze(root->elements[1])) + { + return false; + } + }else if(root->nodeType == Const::NODE_PATTERN && !root->elements.empty()) + { + if(root->elements[0]->nodeType == Const::VARIABLE && !analyze(root->elements[0],true,Const::NODE)) + { + return false; + } + for(int i=1; ielements.size(); i++) + { + if(!analyze(root->elements[i])) + { + return false; + } + } + }else if(root->nodeType == Const::RELATIONSHIP_DETAILS && !root->elements.empty()) + { + if(root->elements[0]->nodeType == Const::VARIABLE && !analyze(root->elements[0],true,Const::RELATIONSHIP)) + { + return false; + } + for(int i=1; ielements.size(); i++) + { + if(!analyze(root->elements[i])) + { + return false; + } + } + }else if(root->nodeType == Const::LIST_ITERATE) + { + if(!analyze(root->elements[0],true)) + { + return false; + } + if(!analyze(root->elements[1])) + { + return false; + } + }else if(root->nodeType == Const::NON_ARITHMETIC_OPERATOR && root->elements[0]->nodeType == Const::VARIABLE) + { + if(root->elements[1]->nodeType == Const::LIST_INDEX_RANGE && !analyze(root->elements[0], false, Const::LIST)) + { + return false; + }else if(root->elements[1]->nodeType == Const::LIST_INDEX && root->elements[1]->elements[0]->nodeType == Const::DECIMAL && !analyze(root->elements[0], false, "LIST")) + { + return false; + }else if (root->elements[1]->nodeType == Const::PROPERTY_LOOKUP && !analyze(root->elements[0], false, Const::LOOKUP)) + { + return false; + } + }else if(root->nodeType == Const::EXISTS) + { + scopeManager->enterScope(); + for(int i=0; ielements.size(); i++) + { + if(!analyze(root->elements[i])) + { + return false; + } + } + scopeManager->exitScope(); + + }else if(root->nodeType == Const::WITH) + { + for(int i=0; ielements.size(); i++) + { + if(!analyze(root->elements[i])) + { + return false; + } + } + + clearTemp(); + auto *node = root->elements[0]->elements[0]; + for (auto* child: node->elements) + { + if(child->nodeType == Const::AS) + { + string tempType; + if(child->elements[0]->nodeType == Const::VARIABLE) + { + tempType = scopeManager->getType(child->elements[0]->value); + }else if(child->elements[0]->nodeType == Const::PROPERTIES_MAP) + { + tempType = Const::MAP; + }else if(child->elements[0]->nodeType == Const::LIST) + { + tempType = Const::LIST; + }else + { + tempType = Const::ANY; + } + pair x = pair(child->elements[1]->value,tempType); + temp->insert(x); + } else if(child->nodeType == Const::VARIABLE) + { + string tempType = scopeManager->getType(child->value); + pair x = pair(child->value,tempType); + temp->insert(x); + } + else + { + reportError("use 'as' keyword to assign it to new variable" + node->value, node); + return false; + } + } + scopeManager->clearTable(); + for (auto tempNode = temp->begin(); tempNode != temp->end(); ++tempNode) { + scopeManager->addSymbol(tempNode->first,tempNode->second); + } + + } + else + { + for(int i=0; ielements.size(); i++) + { + if(!analyze(root->elements[i])) + { + return false; + } + } + } + return true; +} + +// Check for variable declarations +bool SemanticAnalyzer::checkVariableDeclarations(ASTNode* node, string type) { + if (!scopeManager->lookup(node->value)){ + // If variable is not in current scope, add it + scopeManager->addSymbol(node->value, type); + }else if(scopeManager->lookup(node->value) == type) + { + return true; + } + else { + reportError("Varmiable already declared: " + node->value, node); + return false; + } + + return true; +} + +// Check for function definitions +void SemanticAnalyzer::clearTemp() +{ + temp->clear(); +} + +bool SemanticAnalyzer::checkVariableUsage(ASTNode* node, string type) +{ + if(!(scopeManager->lookup(node->value))) + { + reportError("Variable is not defined in this scope: " + node->value, node); + return false; + }else if(scopeManager->lookup(node->value) && type == Const::ANY) + { + return true; + }else if (scopeManager->lookup(node->value) && scopeManager->lookup(node->value) == type) + { + return true; + } + else if (type == "LOOKUP" && (scopeManager->lookup(node->value) == Const::NODE || + scopeManager->lookup(node->value) == Const::RELATIONSHIP || + scopeManager->lookup(node->value) == Const::MAP)) + { + return true; + } + else + { + reportError("Variable type mismatch: " + node->value, node); + return false; + } + +} + +// Report errors +void SemanticAnalyzer::reportError(const std::string &message, ASTNode* node) { + Logger logger; + logger.error(message); +} diff --git a/src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.h b/src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.h new file mode 100644 index 00000000..bae8eb81 --- /dev/null +++ b/src/query/processor/cypher/semanticanalyzer/SemanticAnalyzer.h @@ -0,0 +1,45 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#include "../astbuilder/ASTNode.h" +#include "ScopeManager.h" // Include scope manager header + +#ifndef SEMANTICANALYZER_H +#define SEMANTICANALYZER_H + +class SemanticAnalyzer { +public: + // Constructor + SemanticAnalyzer(); + + // Destructor + ~SemanticAnalyzer(); + + // Public method to analyze the AST + bool analyze(ASTNode* root, bool canDefine = false, string type = "ANY"); + + ScopeManager* getScopeManager(); + unordered_map *temp; + +private: + ScopeManager* scopeManager; // Add a ScopeManager instance + void clearTemp(); + // Private helper methods + bool checkVariableDeclarations(ASTNode* node, string type); + bool checkVariableUsage(ASTNode* node, string type); + + // Method to report errors + void reportError(const std::string &message, ASTNode* node); +}; + +#endif //SEMANTICANALYZER_H diff --git a/src/query/processor/cypher/util/Const.cpp b/src/query/processor/cypher/util/Const.cpp new file mode 100644 index 00000000..28324753 --- /dev/null +++ b/src/query/processor/cypher/util/Const.cpp @@ -0,0 +1,135 @@ +// +// Created by thamindu on 9/28/24. +// + +#include "Const.h" +using namespace std; + +string Const::UNION = "UNION"; +string Const::ALL = "ALL"; +string Const::SINGLE_QUERY = "SINGLE_QUERY"; +string Const::MULTI_PART_QUERY = "MULTI_PART_QUERY"; +string Const::MATCH = "MATCH"; +string Const::OPTIONAL = "OPTIONAL"; +string Const::UNWIND = "UNWIND"; +string Const::AS = "AS"; +string Const::MERGE = "MERGE"; +string Const::ON_CREATE = "ON_CREATE"; +string Const::ON_MATCH = "ON_MATCH"; +string Const::CREATE = "CREATE"; +string Const::MULTIPLE_SET = "MULTIPLE_SET"; +string Const::SET = "SET"; +string Const::SET_EUAL = "SET_="; +string Const::SET_PLUS_EQAL = "SET_+="; +string Const::DELETE = "DELETE"; +string Const::DETACH = "DETACH"; +string Const::REMOVE_LIST = "REMOVE_LIST"; +string Const::REMOVE = "REMOVE"; +string Const::CALL = "CALL"; +string Const::STAR = "*"; +string Const::YIELD_ITEMS = "YIELD_ITEMS"; +string Const::YIELD = "YIELD"; +string Const::WITH = "WITH"; +string Const::RETURN = "RETURN"; +string Const::DISTINCT = "DISTINCT"; +string Const::RETURN_BODY = "RETURN_BODY"; +string Const::ORDERED_BY = "ORDERED_BY"; +string Const::SKIP = "SKIP"; +string Const::LIMIT = "LIMIT"; +string Const::ASC = "ASC"; +string Const::DESC = "DESC"; +string Const::WHERE = "WHERE"; +string Const::PATTERN = "PATTERN"; +string Const::PATTERN_ELEMENTS = "PATTERN_ELEMENTS"; +string Const::NODE_PATTERN = "NODE_PATTERN"; +string Const::PATTERN_ELEMENT_CHAIN = "PATTERN_ELEMENT_CHAIN"; +string Const::RELATIONSHIP_PATTTERN = "RELATIONSHIP_PATTTERN"; +string Const::UNIDIRECTION_ARROW = "UNIDIRECTION_ARROW"; +string Const::RELATIONSHIP_DETAILS = "RELATIONSHIP_DETAILS"; +string Const::RELATIONSHIP_TYPES = "RELATIONSHIP_TYPES"; +string Const::NODE_LABELS = "NODE_LABELS"; +string Const::NODE_LABEL = "NODE_LABEL"; +string Const::RANGE = "RANGE"; +string Const::PROPERTY = "PROPERTY"; +string Const::OR = "OR"; +string Const::XOR = "XOR"; +string Const::AND = "AND"; +string Const::NOT = "RETURN_BODY"; +string Const::COMPARISON = "COMPARISON"; +string Const::GREATER_THAN = ">"; +string Const::GREATER_THAN_LOWER_THAN = "<>"; +string Const::DOUBLE_EQUAL = "=="; +string Const::LOWER_THAN = "<"; +string Const::GREATER_THAN_OR_EQUAL = ">="; +string Const::LOWER_THAN_OR_EQUAL = "<="; +string Const::PREDICATE_EXPRESSIONS = "PREDICATE_EXPRESSIONS"; +string Const::STRING_PREDICATES = "STRING_PREDICATES"; +string Const::LIST_PREDICATES = "LIST_PREDICATES"; +string Const::NULL_PREDICATES = "NULL_PREDICATES"; +string Const::STARTS_WITH = "UNIDIRECTION_ARROW"; +string Const::ENDS_WITH = "ENDS_WITH"; +string Const::CONTAINS = "CONTAINS"; +string Const::IN = "IN"; +string Const::IS_NOT_NULL = "IS_NOT_NULL"; +string Const::IS_NULL = "IS_NULL"; +string Const::ADD_OR_SUBSTRACT = "ADD_OR_SUBSTRACT"; +string Const::PLUS = "+"; +string Const::MINUS = "-"; +string Const::MULTIPLY_DIVID_MODULO = "MULTIPLY_DIVID_MODULO"; +string Const::DIVIDE = "/"; +string Const::POWER_OF = "POWER_OF"; +string Const::POWER = "^"; +string Const::UNARY_PLUS = "UNARY_+"; +string Const::UNARY_MINUS = "UNARY_-"; +string Const::NON_ARITHMETIC_OPERATOR = "NON_ARITHMETIC_OPERATOR"; +string Const::LIST_INDEX_RANGE = "LIST_INDEX_RANGE"; +string Const::LIST_INDEX = "LIST_INDEX"; +string Const::PROPERTY_LOOKUP = "PROPERTY_LOOKUP"; +string Const::COUNT = "COUNT"; +string Const::CASE_PATTERN = "CASE_PATTERN"; +string Const::CASE_EXPRESSION = "CASE_EXPRESSION"; +string Const::ELSE_EXPRESSION = "ELSE_EXPRESSION"; +string Const::CASE = "CASE"; +string Const::WHEN = "WHEN"; +string Const::THEN = "THEN"; +string Const::LIST_COMPREHENSION = "LIST_COMPREHENSION"; +string Const::PATTERN_COMPREHENSION = "PATTERN_COMPREHENSION"; +string Const::FILTER_RESULT = "FILTER_RESULT"; +string Const::EQUAL = "="; +string Const::ANY = "ANY"; +string Const::NONE = "NONE"; +string Const::SINGLE = "SINGLE"; +string Const::FILTER_EXPRESSION = "FILTER_EXPRESSION"; +string Const::LIST_ITERATE = "LIST_ITERATE"; +string Const::FUNCTION_BODY = "ELSE_EXPRESSION"; +string Const::ARGUMENTS = "ARGUMENTS"; +string Const::FUNCTION_NAME = "FUNCTION_NAME"; +string Const::FUNCTION = "FUNCTION"; +string Const::EXISTS = "EXISTS"; +string Const::EXPLICIT_PROCEDURE = "EXPLICIT_PROCEDURE"; +string Const::IMPLICIT_PROCEDURE = "IMPLICIT_PROCEDURE"; +string Const::PROCEDURE_RESULT = "PROCEDURE_RESULT"; +string Const::PROCEDURE = "PROCEDURE"; +string Const::PROCEDURE_NAME = "PROCEDURE_NAME"; +string Const::NAMESPACE = "NAMESPACE"; +string Const::VARIABLE = "VARIABLE"; +string Const::NULL_STRING = "NULL"; +string Const::STRING = "STRING"; +string Const::BOOLEAN = "BOOLEAN"; +string Const::DECIMAL = "DECIMAL"; +string Const::HEX = "HEX"; +string Const::OCTAL = "OCTAL"; +string Const::EXP_DECIMAL = "EXP_DECIMAL"; +string Const::REGULAR_DECIMAL = "REGULAR_DECIMAL"; +string Const::LIST = "LIST"; +string Const::PROPERTIES_MAP = "PROPERITES_MAP"; +string Const::PARAMETER = "PARAMETER"; +string Const::SYMBOLIC_WORD = "SYMBOLIC_WORD"; +string Const::RESERVED_WORD = "RESERVED_WORD"; +string Const::LEFT_ARRROW = "LEFT_ARRROW"; +string Const::RIGHT_ARROW = "RIGHT_ARROW"; +string Const::MAP = "MAP"; +string Const::PATH_PATTERN = "PATH_PATTERN"; +string Const::NODE = "NODE"; +string Const::RELATIONSHIP = "RELATIONSHIP"; +string Const::LOOKUP = "LOOKUP"; diff --git a/src/query/processor/cypher/util/Const.h b/src/query/processor/cypher/util/Const.h new file mode 100644 index 00000000..b518b3c5 --- /dev/null +++ b/src/query/processor/cypher/util/Const.h @@ -0,0 +1,144 @@ +// +// Created by thamindu on 9/28/24. +// +#include + +#ifndef CONST_H +#define CONST_H +using namespace std; + +class Const +{ +public: + static string UNION; + static string ALL; + static string SINGLE_QUERY; + static string MULTI_PART_QUERY; + static string MATCH; + static string OPTIONAL; + static string UNWIND; + static string AS; + static string MERGE; + static string ON_CREATE; + static string ON_MATCH; + static string CREATE; + static string MULTIPLE_SET; + static string SET; + static string SET_PLUS_EQAL; + static string SET_EUAL; + static string DELETE; + static string DETACH; + static string REMOVE_LIST; + static string REMOVE; + static string CALL; + static string STAR; + static string YIELD_ITEMS; + static string YIELD; + static string WITH; + static string RETURN; + static string DISTINCT; + static string RETURN_BODY; + static string ORDERED_BY; + static string SKIP; + static string LIMIT; + static string ASC; + static string DESC; + static string WHERE; + static string PATTERN; + static string PATTERN_ELEMENTS; + static string NODE_PATTERN; + static string PATTERN_ELEMENT_CHAIN; + static string RELATIONSHIP_PATTTERN; + static string UNIDIRECTION_ARROW; + static string RELATIONSHIP_DETAILS; + static string RELATIONSHIP_TYPES; + static string NODE_LABELS; + static string NODE_LABEL; + static string RANGE; + static string PROPERTY; + static string OR; + static string XOR; + static string AND; + static string NOT; + static string COMPARISON; + static string GREATER_THAN; + static string GREATER_THAN_LOWER_THAN; + static string DOUBLE_EQUAL; + static string LOWER_THAN; + static string LOWER_THAN_OR_EQUAL; + static string GREATER_THAN_OR_EQUAL; + static string PREDICATE_EXPRESSIONS; + static string STRING_PREDICATES; + static string LIST_PREDICATES; + static string NULL_PREDICATES; + static string STARTS_WITH; + static string ENDS_WITH; + static string CONTAINS; + static string IN; + static string IS_NOT_NULL; + static string IS_NULL; + static string ADD_OR_SUBSTRACT; + static string PLUS; + static string MINUS; + static string MULTIPLY_DIVID_MODULO; + static string DIVIDE; + static string POWER_OF; + static string POWER; + static string UNARY_PLUS; + static string UNARY_MINUS; + static string NON_ARITHMETIC_OPERATOR; + static string LIST_INDEX_RANGE; + static string LIST_INDEX; + static string PROPERTY_LOOKUP; + static string COUNT; + static string CASE_PATTERN; + static string CASE_EXPRESSION; + static string ELSE_EXPRESSION; + static string CASE; + static string WHEN; + static string THEN; + static string LIST_COMPREHENSION; + static string FILTER_RESULT; + static string PATTERN_COMPREHENSION; + static string EQUAL; + static string ANY; + static string NONE; + static string SINGLE; + static string FILTER_EXPRESSION; + static string LIST_ITERATE; + static string FUNCTION_BODY; + static string ARGUMENTS; + static string FUNCTION_NAME; + static string FUNCTION; + static string EXISTS; + static string EXPLICIT_PROCEDURE; + static string IMPLICIT_PROCEDURE; + static string PROCEDURE_RESULT; + static string PROCEDURE_NAME; + static string PROCEDURE; + static string NAMESPACE; + static string VARIABLE; + static string NULL_STRING; + static string STRING; + static string BOOLEAN; + static string DECIMAL; + static string HEX; + static string OCTAL; + static string EXP_DECIMAL; + static string REGULAR_DECIMAL; + static string LIST; + static string PROPERTIES_MAP; + static string PARAMETER; + static string SYMBOLIC_WORD; + static string RESERVED_WORD; + static string LEFT_ARRROW; + static string RIGHT_ARROW; + + static string MAP; + static string PATH_PATTERN; + static string NODE; + static string RELATIONSHIP; + static string LOOKUP; +}; + +#endif //CONST_H