Skip to content

Commit

Permalink
Query compilation framework. (TuGraph-family#687)
Browse files Browse the repository at this point in the history
* compilation execution framework.

* execution framework.

* remove static_var usage in data structures.

* test framework.

* generate code on current directory

* delete files after executions.

* fix bugs in test framework.

* LLVM framework

* LLVM backend

* fix compilation error.

* fix lint error.

* fix lint error.

* fix lint error.

---------

Co-authored-by: Ke Huang <[email protected]>
  • Loading branch information
RTEnzyme and spasserby authored Oct 31, 2024
1 parent 4d10a4a commit 1bc9d5f
Show file tree
Hide file tree
Showing 15 changed files with 1,140 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "deps/tugraph-db-browser"]
path = deps/tugraph-db-browser
url = https://github.com/TuGraph-family/tugraph-db-browser.git
[submodule "deps/buildit"]
path = deps/buildit
url = "https://github.com/RTEnzyme/buildit.git"
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ if (BUILD_PROCEDURE)
add_subdirectory(procedures)
endif (BUILD_PROCEDURE)



# buildit
# add_custom_target(buildit
# COMMAND ${CMAKE_COMMAND} -E chdir ${EXTERNAL_PROJECT_DIR} $(MAKE)
# COMMENT "Building external project"
# )
# add_dependencies(my_program build_external_project)

# unit_test
if (WITH_TESTS)
add_subdirectory(test)
Expand Down
1 change: 1 addition & 0 deletions deps/buildit
Submodule buildit added at 734725
25 changes: 25 additions & 0 deletions src/BuildCypherLib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ find_package(PythonInterp 3)
find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED)
#antlr4-runtime
find_package(antlr4-runtime REQUIRED)
# find_package(LLVM REQUIRED CONFIG)
set(ANTRL4_LIBRARY antlr4-runtime.a)

set(TARGET_LGRAPH_CYPHER_LIB lgraph_cypher_lib)
set(EXTERNAL_PROJECT_DIR "${CMAKE_SOURCE_DIR}/deps/buildit")
add_custom_target(buildit
COMMAND ${CMAKE_COMMAND} -E chdir ${EXTERNAL_PROJECT_DIR} $(MAKE)
COMMENT "Building external project"
)


set(LGRAPH_CYPHER_SRC # find cypher/ -name "*.cpp" | sort
cypher/arithmetic/agg_funcs.cpp
Expand Down Expand Up @@ -63,6 +70,10 @@ set(LGRAPH_CYPHER_SRC # find cypher/ -name "*.cpp" | sort
cypher/execution_plan/plan_cache/plan_cache_param.cpp
cypher/execution_plan/plan_cache/plan_cache.cpp
cypher/execution_plan/scheduler.cpp
cypher/experimental/data_type/field_data.h
cypher/experimental/expressions/cexpr.cpp
cypher/experimental/expressions/kernal/binary.cpp
# cypher/experimental/jit/TuJIT.cpp
cypher/filter/filter.cpp
cypher/filter/iterator.cpp
cypher/graph/graph.cpp
Expand Down Expand Up @@ -95,10 +106,24 @@ target_include_directories(${TARGET_LGRAPH_CYPHER_LIB} PUBLIC
${ANTLR4_INCLUDE_DIR}
${CMAKE_CURRENT_LIST_DIR}/cypher)

include_directories(
${CMAKE_SOURCE_DIR}/deps/buildit/include
${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})

target_link_directories(${TARGET_LGRAPH_CYPHER_LIB} PUBLIC
${CMAKE_SOURCE_DIR}/deps/buildit/lib)

add_dependencies(${TARGET_LGRAPH_CYPHER_LIB} buildit)

target_link_libraries(${TARGET_LGRAPH_CYPHER_LIB} PUBLIC
${ANTRL4_LIBRARY}
geax_isogql
# ${CMAKE_SOURCE_DIR}/deps/buildit/build/libbuildit.a
lgraph)

target_link_libraries(${TARGET_LGRAPH_CYPHER_LIB} PRIVATE
lgraph_server_lib)

# llvm_map_components_to_libnames(llvm_libs Core Support)
# target_link_libraries(${TARGET_LGRAPH_CYPHER_LIB} PRIVATE ${llvm_libs})
214 changes: 214 additions & 0 deletions src/cypher/experimental/data_type/field_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/**
* Copyright 2022 AntGroup CO., Ltd.
*
* 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.
*/
#pragma once
#include <builder/dyn_var.h>
#include <builder/static_var.h>
#include <variant>
#include <unordered_map>
#include "core/data_type.h"
#include "cypher/cypher_types.h"
#include "cypher/cypher_exception.h"

using builder::static_var;
using builder::dyn_var;
using lgraph::FieldType;

namespace cypher {
namespace compilation {

struct CScalarData {
static constexpr const char* type_name = "CScalarData";
std::variant<
std::monostate, // Represent the null state
dyn_var<int16_t>,
dyn_var<int>,
dyn_var<int64_t>,
dyn_var<float>,
dyn_var<double>
> constant_;

lgraph::FieldType type_;

CScalarData() {
type_ = lgraph_api::FieldType::NUL;
}

CScalarData(CScalarData &&data)
: constant_(std::move(data.constant_)), type_(data.type_) {}

CScalarData(const CScalarData& other)
: constant_(other.constant_), type_(other.type_) {}

explicit CScalarData(const lgraph::FieldData& other) {
type_ = other.type;
switch (other.type) {
case lgraph::FieldType::NUL:
constant_.emplace<std::monostate>();
break;
case lgraph::FieldType::INT64:
constant_.emplace<dyn_var<int64_t>>((int64_t)other.integer());
break;
default:
CYPHER_TODO();
}
}

explicit CScalarData(int64_t integer) {
constant_.emplace<dyn_var<int64_t>>(integer);
type_ = lgraph::FieldType::INT64;
}

explicit CScalarData(const static_var<int64_t> &integer)
: type_(FieldType::INT64) {
constant_ = (dyn_var<int64_t>) integer;
}

explicit CScalarData(const dyn_var<int64_t> &integer)
: constant_(integer), type_(FieldType::INT64) {}

explicit CScalarData(dyn_var<int64_t>&& integer)
: constant_(std::move(integer)), type_(FieldType::INT64) {}

inline dyn_var<int64_t> integer() const {
switch (type_) {
case FieldType::NUL:
case FieldType::BOOL:
throw std::bad_cast();
case FieldType::INT8:
return std::get<dyn_var<int32_t>>(constant_);
case FieldType::INT16:
return std::get<dyn_var<int32_t>>(constant_);
case FieldType::INT32:
return std::get<dyn_var<int>>(constant_);
case FieldType::INT64:
return std::get<dyn_var<int64_t>>(constant_);
case FieldType::FLOAT:
case FieldType::DOUBLE:
case FieldType::DATE:
case FieldType::DATETIME:
case FieldType::STRING:
case FieldType::BLOB:
case FieldType::POINT:
case FieldType::LINESTRING:
case FieldType::POLYGON:
case FieldType::SPATIAL:
case FieldType::FLOAT_VECTOR:
throw std::bad_cast();
}
return dyn_var<int64_t>(0);
}

inline dyn_var<double> real() const {
switch (type_) {
case FieldType::NUL:
case FieldType::BOOL:
case FieldType::INT8:
case FieldType::INT16:
case FieldType::INT32:
case FieldType::INT64:
throw std::bad_cast();
case FieldType::FLOAT:
std::get<dyn_var<float>>(constant_);
case FieldType::DOUBLE:
std::get<dyn_var<double>>(constant_);
case FieldType::DATE:
case FieldType::DATETIME:
case FieldType::STRING:
case FieldType::BLOB:
case FieldType::POINT:
case FieldType::LINESTRING:
case FieldType::POLYGON:
case FieldType::SPATIAL:
case FieldType::FLOAT_VECTOR:
throw std::bad_cast();
}
return dyn_var<double>(0);
}

dyn_var<int64_t> Int64() const {
return std::get<dyn_var<int64_t>>(constant_);
}

inline bool is_integer() const {
return type_ >= FieldType::INT8 && type_ <= FieldType::INT64;
}

inline bool is_real() const {
return type_ == FieldType::DOUBLE || type_ == FieldType::FLOAT;
}

bool is_null() const { return type_ == lgraph::FieldType::NUL; }

bool is_string() const { return type_ == lgraph::FieldType::STRING; }

CScalarData& operator=(CScalarData&& other) noexcept {
if (this != &other) {
constant_ = std::move(other.constant_);
type_ = std::move(other.type_);
}
return *this;
}

CScalarData& operator=(const CScalarData& other) {
if (this != &other) {
constant_ = other.constant_;
type_ = other.type_;
}
return *this;
}

CScalarData operator+(const CScalarData& other) const;
};

struct CFieldData {
enum FieldType { SCALAR, ARRAY, MAP} type;

CScalarData scalar;
std::vector<CFieldData>* array = nullptr;
std::unordered_map<std::string, CFieldData>* map = nullptr;

CFieldData() : type(SCALAR) {}

CFieldData(const CFieldData &data) : type(data.type), scalar(data.scalar) {}

explicit CFieldData(const CScalarData& scalar) : type(SCALAR), scalar(scalar) {}

CFieldData& operator=(const CFieldData& data) {
this->type = data.type;
this->scalar = data.scalar;
return *this;
}

CFieldData& operator=(CFieldData&& data) {
this->type = std::move(data.type);
this->scalar = std::move(data.scalar);
return *this;
}

explicit CFieldData(const static_var<int64_t>& scalar) : type(SCALAR), scalar(scalar) {}

bool is_null() const { return type == SCALAR && scalar.is_null(); }

bool is_string() const { return type == SCALAR && scalar.is_string(); }

bool is_integer() const { return type == SCALAR && scalar.is_integer(); }

bool is_real() const { return type == SCALAR && scalar.is_real(); }

CFieldData operator+(const CFieldData& other) const;

CFieldData operator-(const CFieldData& other) const;
};
} // namespace compilation
} // namespace cypher
92 changes: 92 additions & 0 deletions src/cypher/experimental/data_type/record.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* Copyright 2022 AntGroup CO., Ltd.
*
* 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.
*/

#pragma once

#include <utility>
#include "core/data_type.h"
#include "cypher/cypher_types.h"
#include "cypher/cypher_exception.h"
#include "parser/data_typedef.h"
#include "graph/node.h"
#include "graph/relationship.h"
#include "cypher/resultset/record.h"
#include "experimental/data_type/field_data.h"

namespace cypher {

struct SymbolTable;
class RTContext;

namespace compilation {
struct CEntry {
compilation::CFieldData constant_;
cypher::Node* node_ = nullptr;
cypher::Relationship* relationship_ = nullptr;

enum RecordEntryType {
UNKNOWN = 0,
CONSTANT,
NODE,
RELATIONSHIP,
VAR_LEN_RELP,
HEADER, // TODO(anyone) useless?
NODE_SNAPSHOT,
RELP_SNAPSHOT,
} type_;

CEntry() = default;

explicit CEntry(const cypher::Entry& entry) {
switch (entry.type) {
case cypher::Entry::CONSTANT: {
constant_ = CFieldData(CScalarData(entry.constant.scalar));
type_ = CONSTANT;
break;
}
case cypher::Entry::NODE: {
node_ = entry.node;
type_ = NODE;
break;
}
case cypher::Entry::RELATIONSHIP: {
relationship_ = entry.relationship;
type_ = RELATIONSHIP;
break;
}
default:
CYPHER_TODO();
}
}

explicit CEntry(const CFieldData &data) : constant_(data), type_(CONSTANT) {}

explicit CEntry(CFieldData&& data) : constant_(std::move(data)), type_(CONSTANT) {}

explicit CEntry(const CScalarData& scalar) : constant_(scalar), type_(CONSTANT) {}
};

struct CRecord { // Should be derived from cypher::Record
std::vector<CEntry> values;

CRecord() = default;

explicit CRecord(const cypher::Record &record) {
for (auto& entry : record.values) {
values.emplace_back(entry);
}
}
};
} // namespace compilation
} // namespace cypher
Loading

0 comments on commit 1bc9d5f

Please sign in to comment.