Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test only #723

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
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"
1 change: 1 addition & 0 deletions deps/buildit
Submodule buildit added at 734725
19 changes: 19 additions & 0 deletions src/BuildCypherLib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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)
Expand Down Expand Up @@ -55,7 +56,13 @@ set(LGRAPH_CYPHER_SRC # find cypher/ -name "*.cpp" | sort
cypher/execution_plan/ops/op_node_by_id_seek.cpp
cypher/execution_plan/ops/op_traversal.cpp
cypher/execution_plan/ops/op_gql_remove.cpp
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 @@ -88,10 +95,22 @@ 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)

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})
40 changes: 25 additions & 15 deletions src/cypher/arithmetic/arithmetic_expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1425,13 +1425,20 @@ void ArithOperandNode::SetEntity(const std::string &alias, const std::string &pr
}

void ArithOperandNode::SetParameter(const std::string &param, const SymbolTable &sym_tab) {
type = AR_OPERAND_PARAMETER;
variadic.alias = param;
auto it = sym_tab.symbols.find(param);
if (it == sym_tab.symbols.end()) {
throw lgraph::CypherException("Parameter not defined: " + param);
if (std::isdigit(param[1])) {
// query plan parameter
type = AR_OPERAND_CONSTANT;
constant = sym_tab.param_tab_->at(param);
} else {
// named parameter
type = AR_OPERAND_PARAMETER;
variadic.alias = param;
auto it = sym_tab.symbols.find(param);
if (it == sym_tab.symbols.end()) {
throw lgraph::CypherException("Parameter not defined: " + param);
}
variadic.alias_idx = it->second.id;
}
variadic.alias_idx = it->second.id;
}

void ArithOperandNode::RealignAliasId(const SymbolTable &sym_tab) {
Expand All @@ -1441,17 +1448,20 @@ void ArithOperandNode::RealignAliasId(const SymbolTable &sym_tab) {
variadic.alias_idx = it->second.id;
}

cypher::FieldData GenerateCypherFieldData(const parser::Expression &expr) {
if (expr.type != parser::Expression::LIST && expr.type != parser::Expression::MAP) {
cypher::FieldData GenerateCypherFieldData(const parser::Expression &expr,
const SymbolTable &sym_tab) {
if (expr.type == parser::Expression::PARAMETER) {
return cypher::FieldData(sym_tab.param_tab_->at(expr.String()));
} else if (expr.type != parser::Expression::LIST
&& expr.type != parser::Expression::MAP) {
return cypher::FieldData(parser::MakeFieldData(expr));
}
if (expr.type == parser::Expression::LIST) {
} else if (expr.type == parser::Expression::LIST) {
std::vector<cypher::FieldData> list;
for (auto &e : expr.List()) list.emplace_back(GenerateCypherFieldData(e));
for (auto &e : expr.List()) list.emplace_back(GenerateCypherFieldData(e, sym_tab));
return cypher::FieldData(std::move(list));
} else {
std::unordered_map<std::string, cypher::FieldData> map;
for (auto &e : expr.Map()) map.emplace(e.first, GenerateCypherFieldData(e.second));
for (auto &e : expr.Map()) map.emplace(e.first, GenerateCypherFieldData(e.second, sym_tab));
return cypher::FieldData(std::move(map));
}
}
Expand Down Expand Up @@ -1494,13 +1504,13 @@ void ArithOperandNode::Set(const parser::Expression &expr, const SymbolTable &sy
{
/* e.g. [1,3,5,7], [1,3,5.55,'seven'] */
type = ArithOperandNode::AR_OPERAND_CONSTANT;
constant = GenerateCypherFieldData(expr);
constant = GenerateCypherFieldData(expr, sym_tab);
break;
}
case parser::Expression::MAP:
{
type = ArithOperandNode::AR_OPERAND_CONSTANT;
constant = GenerateCypherFieldData(expr);
constant = GenerateCypherFieldData(expr, sym_tab);
break;
}
default:
Expand Down Expand Up @@ -1650,7 +1660,7 @@ void ArithExprNode::Set(const parser::Expression &expr, const SymbolTable &sym_t
* [n.name, n.age] as op */
bool is_operand = true;
for (auto &e : expr.List()) {
if (!e.IsLiteral()) is_operand = false;
if (!e.IsLiteral() && e.type != parser::Expression::PARAMETER) is_operand = false;
if (e.type == parser::Expression::MAP) is_operand = true;
}
if (!is_operand) {
Expand Down
8 changes: 8 additions & 0 deletions src/cypher/arithmetic/arithmetic_expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -718,11 +718,19 @@ struct ArithExprNode {

void SetOperand(ArithOperandNode::ArithOperandType operand_type,
const cypher::FieldData &data) {
// @todo(anyone) below assertion throws excpetion when set parameter operand.
CYPHER_THROW_ASSERT(operand_type == ArithOperandNode::AR_OPERAND_CONSTANT);
type = AR_EXP_OPERAND;
operand.SetConstant(data);
}

void SetOperandParameter(ArithOperandNode::ArithOperandType operand_type,
const std::string &param, const SymbolTable &sym_tab) {
CYPHER_THROW_ASSERT(operand_type == ArithOperandNode::AR_OPERAND_PARAMETER);
type = AR_EXP_OPERAND;
operand.SetParameter(param, sym_tab);
}

void SetOperandVariable(ArithOperandNode::ArithOperandType operand_type,
const bool &hasMapFieldName = false, const std::string &value_alias = "",
const std::string &map_field_name = "") {
Expand Down
7 changes: 5 additions & 2 deletions src/cypher/execution_plan/execution_plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,11 @@ void ExecutionPlan::_BuildExpandOps(const parser::QueryPart &part, PatternGraph
pattern_graph.symbol_table);
if (pf.type == Property::PARAMETER) {
// TODO(anyone) use record
ae2.SetOperand(ArithOperandNode::AR_OPERAND_PARAMETER,
cypher::FieldData(lgraph::FieldData(pf.value_alias)));
// Fix bugs of parameterized execution:
// MATCH (rachel:Person {name: $name1})-[]->(family:Person)-[:ACTED_IN]->(film)
// <-[:ACTED_IN]-(richard:Person {name: $name2}) RETURN family.name;
ae2.SetOperandParameter(ArithOperandNode::AR_OPERAND_PARAMETER,
pf.value_alias, pattern_graph.symbol_table);
} else if (pf.type == Property::VARIABLE) {
ae2.SetOperandVariable(ArithOperandNode::AR_OPERAND_VARIABLE,
pf.hasMapFieldName, pf.value_alias, pf.map_field_name);
Expand Down
4 changes: 3 additions & 1 deletion src/cypher/execution_plan/ops/op_argument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ Argument::Argument(const SymbolTable *sym_tab)
: OpBase(OpType::ARGUMENT, "Argument"), sym_tab_(sym_tab) {
std::map<size_t, std::pair<std::string, SymbolNode::Type>> ordered_alias;
for (auto &a : sym_tab->symbols) {
if (a.second.scope == SymbolNode::ARGUMENT) {
// WITH [$1, $2, $3] AS coll RETURN size(coll)
// Should ignore the query params in symbole table
if (a.second.scope == SymbolNode::ARGUMENT && a.second.type != SymbolNode::PARAMETER) {
ordered_alias.emplace(a.second.id, std::make_pair(a.first, a.second.type));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ class LocateNodeByIndexedProp : public OptPass {

if (in_filter->ae_left_.type == ArithExprNode::AR_EXP_OPERAND &&
in_filter->ae_left_.operand.type == ArithOperandNode::AR_OPERAND_VARIADIC &&
!in_filter->ae_left_.operand.variadic.entity_prop.empty()) {
!in_filter->ae_left_.operand.variadic.entity_prop.empty() &&
in_filter->ae_right_.type == ArithExprNode::AR_EXP_OPERAND) {
auto right_data = Entry(in_filter->ae_right_.operand.constant);
if (!right_data.IsArray()) CYPHER_TODO();
field = in_filter->ae_left_.operand.variadic.entity_prop;
Expand Down
14 changes: 14 additions & 0 deletions src/cypher/execution_plan/plan_cache/plan_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* 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.
*/
#include "cypher/execution_plan/plan_cache/plan_cache.h"
108 changes: 108 additions & 0 deletions src/cypher/execution_plan/plan_cache/plan_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* 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 <list>
#include <shared_mutex>

#include "parser/clause.h"
#include "parser/data_typedef.h"

namespace cypher {
class ASTCacheObj {
public:
std::vector<parser::SglQuery> stmts;
parser::CmdType cmd;

ASTCacheObj() {}

ASTCacheObj(const std::vector<parser::SglQuery> &stmts, parser::CmdType cmd)
: stmts(stmts), cmd(cmd) {
}

std::vector<parser::SglQuery> Stmt() {
return stmts;
}

parser::CmdType CmdType() {
return cmd;
}
};

template<typename T>
class PlanCacheEntry {
public:
std::string key;
T value;

PlanCacheEntry(const std::string &key, const T &value) : key(key), value(value) {}
};

template<typename Value>
class LRUPlanCache {
typedef PlanCacheEntry<Value> Entry;
std::list<Entry> _item_list;
std::unordered_map<std::string, decltype(_item_list.begin())> _item_map;
size_t _max_size;
mutable std::shared_mutex _mutex;
inline void _KickOut() {
while (_item_map.size() > _max_size) {
auto last_it = _item_list.end();
last_it--;
_item_map.erase(last_it->key);
_item_list.pop_back();
}
}

public:
explicit LRUPlanCache(size_t max_size) : _max_size(max_size) {}

LRUPlanCache() : _max_size(512) {}

void add_plan(std::string param_query, const Value &val) {
std::unique_lock<std::shared_mutex> lock(_mutex);
auto it = _item_map.find(param_query);
if (it == _item_map.end()) {
_item_list.emplace_front(std::move(param_query), val);
_item_map.emplace(_item_list.begin()->key, _item_list.begin());
_KickOut();
} else {
// Overwrite the cached value if the query is already present in the cache.
// And move the entry to the front of the list.
it->second->value = val;
_item_list.splice(_item_list.begin(), _item_list, it->second);
}
}

// Get the cached value for the given parameterized query. Before calling this function,
// you MUST parameterize the query using the fastQueryParam().
bool get_plan(const std::string &param_query, Value &val) {
// parameterized raw query
std::shared_lock<std::shared_mutex> lock(_mutex);
auto it = _item_map.find(param_query);
if (it == _item_map.end()) {
return false;
}
_item_list.splice(_item_list.begin(), _item_list, it->second);
val = it->second->value;
return true;
}

size_t max_size() const { return _max_size; }

size_t current_size() const { return _item_map.size(); }
};

typedef LRUPlanCache<ASTCacheObj> ASTCache;
} // namespace cypher
Loading
Loading