in flex/engines/graph_db/runtime/execute/ops/retrieve/project.cc [836:1012]
static std::optional<std::function<std::unique_ptr<ProjectExprBase>(
const GraphReadInterface& graph,
const std::map<std::string, std::string>& params, const Context& ctx)>>
parse_special_expr(const common::Expression& expr, int alias) {
int tag = -1;
if (is_exchange_index(expr, alias, tag)) {
return [=](const GraphReadInterface& graph,
const std::map<std::string, std::string>& params,
const Context& ctx) -> std::unique_ptr<ProjectExprBase> {
return std::make_unique<DummyGetter>(tag, alias);
};
}
{
int tag;
std::string name;
RTAnyType type;
if (is_property_extract(expr, tag, name, type)) {
return [=](const GraphReadInterface& graph,
const std::map<std::string, std::string>& params,
const Context& ctx) -> std::unique_ptr<ProjectExprBase> {
auto col = ctx.get(tag);
if ((!col->is_optional()) &&
col->column_type() == ContextColumnType::kVertex) {
auto vertex_col = std::dynamic_pointer_cast<IVertexColumn>(col);
if (vertex_col->get_labels_set().size() == 1) {
if (vertex_col->vertex_column_type() == VertexColumnType::kSingle) {
auto typed_vertex_col =
std::dynamic_pointer_cast<SLVertexColumn>(vertex_col);
return create_sl_property_expr(ctx, graph, *typed_vertex_col,
name, type, alias);
} else {
return create_sl_property_expr(ctx, graph, *vertex_col, name,
type, alias);
}
} else {
if (vertex_col->vertex_column_type() ==
VertexColumnType::kMultiple) {
auto typed_vertex_col =
std::dynamic_pointer_cast<MLVertexColumn>(vertex_col);
return create_ml_property_expr(ctx, graph, *typed_vertex_col,
name, type, alias);
} else {
auto typed_vertex_col =
std::dynamic_pointer_cast<MSVertexColumn>(vertex_col);
return create_ml_property_expr(ctx, graph, *typed_vertex_col,
name, type, alias);
}
}
}
return make_project_expr(expr, alias)(graph, params, ctx);
};
}
}
std::string name, lower, upper, target;
common::Value then_value, else_value;
if (is_check_property_in_range(expr, tag, name, lower, upper, then_value,
else_value)) {
return [=](const GraphReadInterface& graph,
const std::map<std::string, std::string>& params,
const Context& ctx) -> std::unique_ptr<ProjectExprBase> {
auto col = ctx.get(tag);
if (col->column_type() == ContextColumnType::kVertex) {
auto vertex_col = std::dynamic_pointer_cast<IVertexColumn>(col);
auto type = expr.operators(0)
.case_()
.when_then_expressions(0)
.when_expression()
.operators(2)
.param()
.data_type();
auto type_ = parse_from_ir_data_type(type);
if (then_value.item_case() != else_value.item_case() ||
then_value.item_case() != common::Value::kI32) {
return make_project_expr(expr, alias)(graph, params, ctx);
}
if (type_ == RTAnyType::kI32Value) {
SPOpr sp(vertex_col,
VertexPropertyBetweenPredicateBeta<int32_t>(
graph, name, params.at(lower), params.at(upper)),
then_value.i32(), else_value.i32());
CaseWhenCollector<decltype(sp), int32_t> collector(ctx);
return std::make_unique<
ProjectExpr<decltype(sp), decltype(collector)>>(std::move(sp),
collector, alias);
} else if (type_ == RTAnyType::kI64Value) {
SPOpr sp(vertex_col,
VertexPropertyBetweenPredicateBeta<int64_t>(
graph, name, params.at(lower), params.at(upper)),
then_value.i32(), else_value.i32());
CaseWhenCollector<decltype(sp), int32_t> collector(ctx);
return std::make_unique<
ProjectExpr<decltype(sp), decltype(collector)>>(std::move(sp),
collector, alias);
} else if (type_ == RTAnyType::kTimestamp) {
if (vertex_col->vertex_column_type() == VertexColumnType::kSingle) {
auto typed_vertex_col =
std::dynamic_pointer_cast<SLVertexColumn>(vertex_col);
SPOpr sp(typed_vertex_col,
VertexPropertyBetweenPredicateBeta<Date>(
graph, name, params.at(lower), params.at(upper)),
then_value.i32(), else_value.i32());
CaseWhenCollector<decltype(sp), int32_t> collector(ctx);
return std::make_unique<
ProjectExpr<decltype(sp), decltype(collector)>>(
std::move(sp), collector, alias);
} else {
SPOpr sp(vertex_col,
VertexPropertyBetweenPredicateBeta<Date>(
graph, name, params.at(lower), params.at(upper)),
then_value.i32(), else_value.i32());
CaseWhenCollector<decltype(sp), int32_t> collector(ctx);
return std::make_unique<
ProjectExpr<decltype(sp), decltype(collector)>>(
std::move(sp), collector, alias);
}
}
}
return make_project_expr(expr, alias)(graph, params, ctx);
};
}
SPPredicateType ptype;
if (is_check_property_cmp(expr, tag, name, target, then_value, else_value,
ptype)) {
return [=](const GraphReadInterface& graph,
const std::map<std::string, std::string>& params,
const Context& ctx) -> std::unique_ptr<ProjectExprBase> {
auto col = ctx.get(tag);
if (col->column_type() == ContextColumnType::kVertex) {
auto vertex_col = std::dynamic_pointer_cast<IVertexColumn>(col);
auto type = expr.operators(0)
.case_()
.when_then_expressions(0)
.when_expression()
.operators(2)
.param()
.data_type();
auto type_ = parse_from_ir_data_type(type);
if (type_ == RTAnyType::kI32Value) {
auto ptr = create_sp_pred_case_when<int32_t>(
ctx, graph, params, vertex_col, ptype, name, target, then_value,
else_value, alias);
if (ptr) {
return ptr;
}
} else if (type_ == RTAnyType::kI64Value) {
auto ptr = create_sp_pred_case_when<int64_t>(
ctx, graph, params, vertex_col, ptype, name, target, then_value,
else_value, alias);
if (ptr) {
return ptr;
}
} else if (type_ == RTAnyType::kTimestamp) {
auto ptr = create_sp_pred_case_when<Date>(
ctx, graph, params, vertex_col, ptype, name, target, then_value,
else_value, alias);
if (ptr) {
return ptr;
}
} else if (type_ == RTAnyType::kStringValue) {
auto ptr = create_sp_pred_case_when<std::string_view>(
ctx, graph, params, vertex_col, ptype, name, target, then_value,
else_value, alias);
if (ptr) {
return ptr;
}
}
}
return make_project_expr(expr, alias)(graph, params, ctx);
};
}
return std::nullopt;
}