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

feat(interactive): support extract intervals from temporal types in GIE #3229

Merged
merged 24 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
66793e6
[IR Runtime] Support `Extract` in Expression
BingqingLyu Sep 13, 2023
7cb0f74
[Graph Proxy] Support Date/DateTime encoding in csr store
BingqingLyu Sep 14, 2023
bb21c8e
[CI Tests] tests for project expression with Extract
BingqingLyu Sep 14, 2023
1635a11
[Proto] add Date/Time/Timestamp in Value in proto
BingqingLyu Sep 18, 2023
c25b613
[IR Runtime] return Date/Time/Timestamp in Result
BingqingLyu Sep 18, 2023
76cb7c2
minor fix
BingqingLyu Sep 18, 2023
e68d488
Merge branch 'main' into ir_runtime_extract
shirly121 Sep 25, 2023
f2f9482
minor fix
BingqingLyu Sep 25, 2023
b89ae7f
[GIE Compiler] support time32 and timestamp data type in cypher
shirly121 Sep 25, 2023
7540dde
Merge branch 'ir_runtime_extract' of github.com:shirly121/GraphScope …
shirly121 Sep 25, 2023
c319e82
Merge branch 'main' into ir_runtime_extract
shirly121 Sep 25, 2023
4f58c24
[IR Expr] refine extract implementation
BingqingLyu Sep 25, 2023
17334c2
local stash
zhanglei1949 Sep 25, 2023
71f167f
Merge branch 'ir_runtime_extract' of https://github.com/shirly121/Gra…
zhanglei1949 Sep 25, 2023
e02250a
fix
zhanglei1949 Sep 25, 2023
42d2638
fix isnull
zhanglei1949 Sep 25, 2023
ab2f66b
merged
zhanglei1949 Sep 26, 2023
a077b0d
minor change
zhanglei1949 Sep 26, 2023
9f60719
refine pattern related ci tests
BingqingLyu Sep 26, 2023
979448c
format
BingqingLyu Sep 26, 2023
b37c026
[GIE Compiler] add doc
shirly121 Sep 26, 2023
5875cef
some code refine
BingqingLyu Oct 16, 2023
c77777b
[GIE Compiler] revert changes with 'Date' in groot DataType
shirly121 Oct 17, 2023
d830d89
Merge branch 'main' into ir_runtime_extract
BingqingLyu Oct 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/interactive_engine/neo4j/supported_cypher.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Note that some Aggregator operators, such as `max()`, we listed here are impleme
| List | Fold expressions into a single list | [] | [] | <input type="checkbox" disabled checked /> | |
| Labels | Get label name of a vertex type | labels() | labels() | <input type="checkbox" disabled checked /> | |
| Type | Get label name of an edge type | type() | type() | <input type="checkbox" disabled checked /> | |
| Extract | Get interval value from a temporal type | \<temporal\>.\<interval\> | \<temporal\>.\<interval\> | <input type="checkbox" disabled checked /> | |



Expand Down
17 changes: 10 additions & 7 deletions flex/codegen/src/graph_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ enum class DataType {
kVertexId = 8,
kEdgeId = 9,
kLength = 10,
kTime = 11,
kDate = 12,
kDateTime = 13,
kDate = 11,
kTime = 12,
kTimeStamp = 13,
kLabelId = 14
};

Expand Down Expand Up @@ -78,8 +78,12 @@ static codegen::DataType common_data_type_pb_2_data_type(
return codegen::DataType::kInt32Array;
case common::DataType::BOOLEAN:
return codegen::DataType::kBoolean;
case common::DataType::DATE:
case common::DataType::DATE32:
return codegen::DataType::kDate;
case common::DataType::TIME32:
return codegen::DataType::kTime;
case common::DataType::TIMESTAMP:
return codegen::DataType::kTimeStamp;
default:
// LOG(FATAL) << "unknown data type";
throw std::runtime_error(
Expand All @@ -106,11 +110,10 @@ static std::string single_common_data_type_pb_2_str(
return "std::vector<int64_t>";
case common::DataType::INT32_ARRAY:
return "std::vector<int32_t>";
case common::DataType::DATE:
case common::DataType::DATE32:
return "Date";
// TODO: support time32 and timestamp
default:
// LOG(FATAL) << "unknown data type";
// return "";
throw std::runtime_error(
"unknown data type when convert common data type to string:" +
std::to_string(static_cast<int>(data_type)));
Expand Down
61 changes: 37 additions & 24 deletions flex/codegen/src/hqps/hqps_expr_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
case common::Logical::WITHIN:
return "< WithIn > ";
case common::Logical::ISNULL:
return "IsNull";
return "NONE =="; // Convert
default:
throw std::runtime_error("unknown logical");
}
Expand Down Expand Up @@ -180,67 +180,67 @@
}

// Evaluate expression and return the result data type.
static common::DataType eval_expr_return_type(const common::Expression& expr) {
std::stack<common::ExprOpr> operator_stack;
std::stack<common::ExprOpr> tmp_stack;
for (auto& opr : expr.operators()) {
auto item_case = opr.item_case();
VLOG(10) << "got opr: " << opr.DebugString();
if (item_case == common::ExprOpr::kBrace) {
auto brace = opr.brace();
if (brace == common::ExprOpr::Brace::ExprOpr_Brace_LEFT_BRACE) {
operator_stack.push(opr);
} else {
while (!operator_stack.empty() &&
operator_stack.top().item_case() != common::ExprOpr::kBrace) {
tmp_stack.push(operator_stack.top());
operator_stack.pop();
}
CHECK(!operator_stack.empty() &&
operator_stack.top().item_case() == common::ExprOpr::kBrace &&
operator_stack.top().brace() ==
common::ExprOpr::Brace::ExprOpr_Brace_LEFT_BRACE)
<< "no left brace found";
operator_stack.pop();
}
} else if (item_case == common::ExprOpr::kLogical ||
common::ExprOpr::kArith) {
operator_stack.push(opr);
} else if (item_case == common::ExprOpr::kConst ||
item_case == common::ExprOpr::kVar ||
item_case == common::ExprOpr::kVars ||
item_case == common::ExprOpr::kVarMap ||
item_case == common::ExprOpr::kParam) {
tmp_stack.push(opr);
} else {
LOG(WARNING) << "not recognized expr opr: " << opr.DebugString();
throw std::runtime_error("not recognized expr opr");
}
}
while (!operator_stack.empty()) {
tmp_stack.push(operator_stack.top());
operator_stack.pop();
}
{
// print tmp_stack
std::stack<common::ExprOpr> tmp_stack_copy = tmp_stack;
std::stringstream ss;
while (!tmp_stack_copy.empty()) {
ss << tmp_stack_copy.top().DebugString() << std::endl;
tmp_stack_copy.pop();
}
VLOG(10) << "tmp_stack: " << ss.str();
}

return tmp_stack.top().node_type().data_type();
}

// Simlutate the calculation of expression, return the result data type.
// convert to prefix expression

/*Build a expression struct from expression*/
class ExprBuilder {
public:

Check notice on line 243 in flex/codegen/src/hqps/hqps_expr_builder.h

View check run for this annotation

codefactor.io / CodeFactor

flex/codegen/src/hqps/hqps_expr_builder.h#L183-L243

Complex Method
ExprBuilder(BuildingContext& ctx, int var_id = 0, bool no_build = false)
: ctx_(ctx) {
if (!no_build) {
Expand Down Expand Up @@ -284,10 +284,21 @@
}
if (j == size) {
LOG(WARNING) << "no right brace found" << j << "size: " << size;
// just add true, since the current expresion has no other expr_oprs
// just add true, since the current expresion has no other expr_ops
AddExprOpr(std::string("true"));
i = j;
}
} else if (expr.has_extract()) {
// special case for extract
auto extract = expr.extract();
if (i + 1 >= size) {
throw std::runtime_error("extract must have a following var/expr");
} else if (expr_ops[i + 1].item_case() != common::ExprOpr::kVar) {
throw std::runtime_error("extract must have a following var/expr");
} else {
AddExtractOpr(extract, expr_ops[i + 1]);
i += 2;
}
} else {
AddExprOpr(expr_ops[i]);
++i;
Expand Down Expand Up @@ -398,28 +409,8 @@
}

case common::ExprOpr::kExtract: {
auto extract = opr.extract();
auto interval = extract.interval();
auto data_time = extract.data_time();
CHECK(data_time.operators_size() == 1)
<< "Currently only support one var in extract";
auto expr_opr = data_time.operators(0);
CHECK(expr_opr.item_case() == common::ExprOpr::kVar)
<< "Currently only support var in extract";
auto expr_var = expr_opr.var();
auto param_const = variable_to_param_const(expr_var, ctx_);
make_var_name_unique(param_const);
func_call_vars_.push_back(param_const);

boost::format formater(EXTRACT_TEMPLATE_STR);
formater % interval_to_str(interval) % param_const.var_name;
auto extract_node_str = formater.str();
expr_nodes_.emplace_back(extract_node_str);

tag_selectors_.emplace_back(
variable_to_tag_id_property_selector(ctx_, expr_var));
VLOG(10) << "extract opr: " << extract_node_str;
break;
LOG(FATAL) << "Should not reach here, Extract op should be handled "
"separately";
}

default:
Expand All @@ -428,6 +419,28 @@
}
}

// Add extract operator with var. Currently not support extract on a compicate
// expression.
void AddExtractOpr(const common::Extract& extract_opr,
const common::ExprOpr& expr_opr) {
CHECK(expr_opr.item_case() == common::ExprOpr::kVar)
<< "Currently only support var in extract";
auto interval = extract_opr.interval();
auto expr_var = expr_opr.var();
auto param_const = variable_to_param_const(expr_var, ctx_);
make_var_name_unique(param_const);
func_call_vars_.push_back(param_const);

boost::format formater(EXTRACT_TEMPLATE_STR);
formater % interval_to_str(interval) % param_const.var_name;
auto extract_node_str = formater.str();
expr_nodes_.emplace_back(extract_node_str);

tag_selectors_.emplace_back(
variable_to_tag_id_property_selector(ctx_, expr_var));
VLOG(10) << "extract opr: " << extract_node_str;
}

// get expr nodes
const std::vector<std::string>& GetExprNodes() const { return expr_nodes_; }

Expand Down
10 changes: 10 additions & 0 deletions flex/engines/hqps_db/core/null_record.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,20 @@ bool operator==(const T& lhs, const None& rhs) {
return IsNull(lhs);
}

template <typename T>
bool operator==(const None& lhs, const T& rhs) {
return IsNull(rhs);
}

template <typename T>
bool operator!=(const T& lhs, const None& rhs) {
return !IsNull(lhs);
}

template <typename T>
bool operator!=(const None& lhs, const T& rhs) {
return !IsNull(rhs);
}
} // namespace gs

#endif // ENGINES_HQPS_ENGINE_NULL_RECORD_H_
2 changes: 1 addition & 1 deletion flex/engines/hqps_db/core/sync_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ class SyncEngine : public BaseEngine {
template <
int... in_col_id, typename CTX_HEAD_T, int cur_alias, int base_tag,
typename... CTX_PREV, typename EXPR, typename... SELECTOR,
typename std::enable_if<((sizeof...(in_col_id) > 1) &&
typename std::enable_if<((sizeof...(in_col_id) >= 1) &&
(sizeof...(in_col_id) ==
sizeof...(SELECTOR)))>::type* = nullptr,
typename RES_T = Context<CTX_HEAD_T, cur_alias, base_tag, CTX_PREV...>>
Expand Down
59 changes: 58 additions & 1 deletion flex/tests/hqps/match_query.h
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,6 @@ struct MatchQuery11Expr1 {
private:
};

// Auto generated query class definition
class MatchQuery11 : public HqpsAppBase<gs::MutableCSRInterface> {
public:
using Engine = SyncEngine<gs::MutableCSRInterface>;
Expand Down Expand Up @@ -744,5 +743,63 @@ class MatchQuery11 : public HqpsAppBase<gs::MutableCSRInterface> {
}
};

struct MatchQuery12Expr0 {
public:
using result_t = bool;
MatchQuery12Expr0() {}

inline auto operator()(Date var0) const {
return gs::DateTimeExtractor<Interval::MONTH>::extract(var0) == 7;
}

private:
};

struct MatchQuery12Expr1 {
public:
using result_t = int64_t;
MatchQuery12Expr1() {}

inline auto operator()(Date var1) const {
return gs::DateTimeExtractor<Interval::MONTH>::extract(var1);
}

private:
};

class MatchQuery12 : public HqpsAppBase<gs::MutableCSRInterface> {
public:
using Engine = SyncEngine<gs::MutableCSRInterface>;
using label_id_t = typename gs::MutableCSRInterface::label_id_t;
using vertex_id_t = typename gs::MutableCSRInterface::vertex_id_t;
// Query function for query class
results::CollectiveResults Query(const gs::MutableCSRInterface& graph) const {
auto ctx0 = Engine::template ScanVertex<gs::AppendOpt::Persist>(
graph, 1, Filter<TruePredicate>());

auto ctx1 = Engine::Project<PROJ_TO_NEW>(
graph, std::move(ctx0),
std::tuple{gs::make_mapper_with_variable<INPUT_COL_ID(0)>(
gs::PropertySelector<Date>("birthday"))});
auto expr0 = gs::make_filter(MatchQuery12Expr0(),
gs::PropertySelector<Date>("None"));
auto ctx2 = Engine::template Select<INPUT_COL_ID(0)>(graph, std::move(ctx1),
std::move(expr0));

auto ctx3 = Engine::Project<PROJ_TO_NEW>(
graph, std::move(ctx2),
std::tuple{gs::make_mapper_with_expr<0>(
MatchQuery12Expr1(), gs::PropertySelector<Date>("None"))});
return Engine::Sink(ctx3, std::array<int32_t, 1>{2});
}
// Wrapper query function for query class
results::CollectiveResults Query(const gs::MutableCSRInterface& graph,
Decoder& decoder) const override {
// decoding params from decoder, and call real query func

return Query(graph);
}
};

} // namespace gs
#endif // TESTS_HQPS_MATCH_QUERY_H_
15 changes: 14 additions & 1 deletion flex/tests/hqps/query_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,20 @@ int main(int argc, char** argv) {

gs::MutableCSRInterface graph(sess);
query.Query(graph, input);
LOG(INFO) << "Finish MatchQuery10 test";
LOG(INFO) << "Finish MatchQuery11 test";
}

{
gs::MatchQuery12 query;
std::vector<char> encoder_array;
gs::Encoder input_encoder(encoder_array);
std::vector<char> output_array;
gs::Encoder output(output_array);
gs::Decoder input(encoder_array.data(), encoder_array.size());

gs::MutableCSRInterface graph(sess);
query.Query(graph, input);
LOG(INFO) << "Finish MatchQuery12 test";
}

LOG(INFO) << "Finish context test.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
DOUBLE_LIST(13),
STRING_LIST(14),
BYTES_LIST(15),
DATE(16);
DATE(16), // represent DATE32
TIME32(17),
TIMESTAMP(18);

private final byte type;

Expand Down Expand Up @@ -115,74 +117,74 @@
}
}

public static DataType parseFromDataType(
com.alibaba.graphscope.groot.common.meta.DataType dataType) {
InternalDataType internalDataType = dataType.getType();
switch (internalDataType) {
case BOOL:
return DataType.BOOL;

case CHAR:
return DataType.CHAR;

case SHORT:
return DataType.SHORT;

case INT:
return DataType.INT;

case LONG:
return DataType.LONG;

case FLOAT:
return DataType.FLOAT;

case DOUBLE:
return DataType.DOUBLE;

case STRING:

case DATE:
return DataType.STRING;

case BYTES:
return DataType.BYTES;

case LIST:
{
switch (InternalDataType.valueOf(dataType.getExpression())) {
case INT:
{
return DataType.INT_LIST;
}
case LONG:
{
return DataType.LONG_LIST;
}
case FLOAT:
{
return DataType.FLOAT_LIST;
}
case DOUBLE:
{
return DataType.DOUBLE_LIST;
}
case STRING:
{
return DataType.STRING_LIST;
}
default:
{
throw new IllegalArgumentException(
"Unsupported property data type " + dataType);
}
}
}
default:
{
throw new IllegalArgumentException(
"Unsupported property data type " + dataType);
}
}
}

Check notice on line 189 in interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/schema/wrapper/DataType.java

View check run for this annotation

codefactor.io / CodeFactor

interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/schema/wrapper/DataType.java#L120-L189

Complex Method
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ private int getDataTypeId(DataType dataType) {
return 9;
case DATE:
return 12;
case TIME32:
return 13;
case TIMESTAMP:
return 14;
default:
throw new UnsupportedOperationException(
"convert from DataType " + dataType + " to ir core is unsupported yet");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,11 @@ private RelDataType deriveType(GraphProperty property) {
case DOUBLE:
return typeFactory.createSqlType(SqlTypeName.DOUBLE);
case DATE:
return typeFactory.createSqlType(
SqlTypeName.DATE); // todo: support Time and DateTime in GraphSchema
return typeFactory.createSqlType(SqlTypeName.DATE);
case TIME32:
return typeFactory.createSqlType(SqlTypeName.TIME);
case TIMESTAMP:
return typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
default:
throw new UnsupportedOperationException(
"type " + property.getDataType().name() + " not supported");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,14 @@ public static DataType toDataType(Object type) {
return DataType.STRING;
case "DT_DATE32":
return DataType.DATE;
case "DT_TIME32":
return DataType.TIME32;
case "TIMESTAMP":
return DataType.TIMESTAMP;
default:
throw new UnsupportedOperationException(
"unsupported primitive type: " + value);
}
} else if ((value = typeMap.get("date")) instanceof Map) {
Object format = ((Map) value).get("date_format");
if (format != null && format.toString().equals("DF_YYYY_MM_DD")) {
return DataType.DATE;
}
}
}
throw new UnsupportedOperationException("unsupported type: " + type);
Expand Down Expand Up @@ -275,6 +274,10 @@ public static final DataType toDataType(int ordinal) {
return DataType.STRING_LIST;
case 12:
return DataType.DATE;
case 13:
return DataType.TIME32;
case 14:
return DataType.TIMESTAMP;
default:
throw new UnsupportedOperationException(
"convert from ir core type " + ordinal + " to DataType is unsupported yet");
Expand Down
Loading
Loading