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

ExtractFilterExprVisitor #3462

Merged
merged 6 commits into from
Dec 27, 2021
Merged

ExtractFilterExprVisitor #3462

merged 6 commits into from
Dec 27, 2021

Conversation

sworduo
Copy link
Contributor

@sworduo sworduo commented Dec 14, 2021

What type of PR is this?

  • [✅] bug
  • feature
  • enhancement

What does this PR do?

fix #3372

Which issue(s)/PR(s) this PR relates to?

#3372

Special notes for your reviewer, ex. impact of this fix, etc:

Additional context:

Checklist:

  • Documentation affected (Please add the label if documentation needs to be modified.)
  • Incompatible (If it is incompatible, please describe it and add corresponding label.)
  • Need to cherry-pick (If need to cherry-pick to some branches, please label the destination version(s).)
  • Performance impacted: Consumes more CPU/Memory

Release notes:

Please confirm whether to reflect in release notes and how to describe:

                                                            `

@yixinglu yixinglu added the ready-for-testing PR: ready for the CI test label Dec 14, 2021
Copy link
Contributor

@yixinglu yixinglu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very impressive. Thx

checkEqual(expr, expect, remain, false);
}
{
// A1 or (A2 and B1) or (A3 and B2) or A4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that there're some parts of this expression could be pushed:

A1 or (A2 and B1) or (A3 and B2) or A4
=>
A1 or A4 or (A2 and B1) or (A3 and B2)
=>
((A1 or A4 or A2) and (A1 or A4 or B1)) or (A3 and B2)
=>
(((A1 or A4 or A2) and (A1 or A4 or B1)) or A3) and (((A1 or A4 or A2) and (A1 or A4 or B1)) or B2)
=>
((A1 or A4 or A2 or A3) and (A1 or A4 or B1 or A3)) and ((A1 or A4 or A2 or B2) and (A1 or A4 or B1 or B2))
=>
(A1 or A4 or A2 or A3) and (A1 or A4 or B1 or A3) and (A1 or A4 or A2 or B2) and (A1 or A4 or B1 or B2)
=>
can be pushed: (A1 or A4 or A2 or A3) 
remain: (A1 or A4 or B1 or A3) and (A1 or A4 or A2 or B2) and (A1 or A4 or B1 or B2)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remained expr could be simplified: (A1 or A4) or ((B1 or A3) and (A2 or B2) and (B1 or B2))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not easy to implement this. In this pr, for simplification, LogicalOr can be split, if and only if just one operand can not be pushed and that operand is LogicalAnd. Maybe this improvement can be implemented in future version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More test cases for different scenarios are necessary to verify the correctness of this pr. However, I can't think of more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense. thanks.

@@ -79,6 +79,15 @@ class LogicalExpression final : public Expression {

bool isLogicalExpr() const override { return true; }

void setLogicalKind(Kind kind) {
if ((kind == Expression::Kind::kLogicalOr || kind == Expression::Kind::kLogicalAnd) &&
(kind_ == Expression::Kind::kLogicalOr || kind_ == Expression::Kind::kLogicalAnd)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

following check maybe better to understand:

(kind == Expression::Kind::kLogicalOr && kind_ == Expression::Kind::kLogicalAnd) ||
        (kind == Expression::Kind::kLogicalAnd && kind_ == Expression::Kind::kLogicalOr)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this function could be renamed: reverseLogicalKind()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void reverseLogicalKind() {
  if (kind_ == kLogicalAnd) {
    kind_ = kLogicalOr;
  } else if (kind_ == kLogicalOr) {
    kind_ = kLogicalAnd;
  } else {
    LOG(FATAL) << "Should not reverser logical expression except and/or kind.";
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's OK

@wey-gu
Copy link
Contributor

wey-gu commented Dec 14, 2021

👍🏻
context: https://discuss.nebula-graph.com.cn/t/topic/6460/40

@codecov-commenter
Copy link

codecov-commenter commented Dec 14, 2021

Codecov Report

Merging #3462 (566ad6d) into master (99f1f7a) will increase coverage by 0.03%.
The diff coverage is 86.63%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3462      +/-   ##
==========================================
+ Coverage   85.19%   85.23%   +0.03%     
==========================================
  Files        1304     1306       +2     
  Lines      121308   122472    +1164     
==========================================
+ Hits       103352   104386    +1034     
- Misses      17956    18086     +130     
Impacted Files Coverage Δ
src/clients/storage/StorageClient.h 100.00% <ø> (ø)
src/clients/storage/StorageClientBase-inl.h 74.61% <ø> (+1.93%) ⬆️
src/codec/RowWriterV2.h 94.44% <ø> (ø)
src/common/datatypes/Value.h 97.87% <ø> (ø)
src/common/time/TimeConversion.h 100.00% <ø> (ø)
src/common/utils/IndexKeyUtils.h 90.37% <0.00%> (-0.57%) ⬇️
src/graph/util/SchemaUtil.cpp 92.05% <0.00%> (-0.78%) ⬇️
src/graph/validator/MutateValidator.h 100.00% <ø> (ø)
src/graph/visitor/ExtractFilterExprVisitor.h 100.00% <ø> (ø)
src/storage/mutate/AddEdgesProcessor.h 100.00% <ø> (ø)
... and 64 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update af74bab...566ad6d. Read the comment docs.

yixinglu
yixinglu previously approved these changes Dec 15, 2021
Copy link
Contributor

@yixinglu yixinglu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines 273 to 277
if (canBePushExprs.empty() || canNotPushExprs.empty()) {
LOG(ERROR) << "Both can be pushed expr and can not push expr should be existed, but not!";
canBePushed_ = false;
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DCHECK(!canBePushExprs.empty());
DCHECK(!canNotPushExprs.empty());

Expression *ExtractFilterExprVisitor::rewriteExpr(std::vector<Expression *> &rel,
std::vector<Expression *> &sharedExprs) {
Expression *newAndExpr;
if (rel.size() > 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DCHECK(!rel.empty())

} else if (expr->kind() == Expression::Kind::kLogicalOr) {
bool isSplit = visitLogicalOr(expr);
if (isSplit) {
DCHECK_EQ(expr->operands().size(), 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DCHECK_EQ(expr->kind(), Expression::Kind::kLogicalAnd);

@@ -156,6 +200,152 @@ void ExtractFilterExprVisitor::visit(LogicalExpression *expr) {
}
}

// @retrun: split or not
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix typo

sharedExprs.emplace_back(newAndExpr);
auto newOrExpr = ExpressionUtils::pushOrs(pool_, sharedExprs);
ExpressionUtils::pullOrs(newOrExpr);
sharedExprs.pop_back();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about deleting this line of code and changing the input parameter type?

Comment on lines 294 to 295
Expression *ExtractFilterExprVisitor::rewriteExpr(std::vector<Expression *> &rel,
std::vector<Expression *> &sharedExprs) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this?

Expression *ExtractFilterExprVisitor::rewriteExpr(std::vector<Expression *> rel,
                                                  std::vector<Expression *> sharedExprs)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's ok, I will modify it later.

return false;
}

void ExtractFilterExprVisitor::ExtractRemainExpr(LogicalExpression *expr,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DCHECK_EQ(expr->kind(), Expression::Kind::kLogicalAnd);

src/common/expression/LogicalExpression.h Show resolved Hide resolved
return;
// @return: whether this logical expr satisfies split condition
bool ExtractFilterExprVisitor::visitLogicalAnd(LogicalExpression *expr, std::vector<bool> &flags) {
// if the size of operands greater than 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DCHECK_EQ(expr->kind(), Expression::Kind::kLogicalAnd);

@@ -156,6 +200,152 @@ void ExtractFilterExprVisitor::visit(LogicalExpression *expr) {
}
}

// @retrun: split or not
bool ExtractFilterExprVisitor::visitLogicalOr(LogicalExpression *expr) {
if (expr->operands().size() <= 2) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DCHECK_EQ(expr->kind(), Expression::Kind::kLogicalOr);

src/graph/visitor/test/ExtractFilterExprVisitorTest.cpp Outdated Show resolved Hide resolved
src/graph/visitor/test/ExtractFilterExprVisitorTest.cpp Outdated Show resolved Hide resolved
@yixinglu
Copy link
Contributor

@sworduo could you format again and fix the lint error since the format of code base has been changed in #3511 ?

@sworduo
Copy link
Contributor Author

sworduo commented Dec 27, 2021

That's ok

@sworduo
Copy link
Contributor Author

sworduo commented Dec 27, 2021

#3511

Hi @yixinglu , when I rebase the latest commit in my branch and run cmake .. It complains that Downloading vesoft-third-party-3.0-x86_64-libc-2.17-gcc-9.2.0-abi-11.sh failed. And I also find that the url https://oss-cdn.nebula-graph.com.cn/third-party/3.0/vesoft-third-party-3.0-x86_64-libc-2.17-gcc-9.2.0-abi-11.sh can not be fetched. The infomation is

<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<RequestId>61C92BA82C1E9335323F0F8E</RequestId>
<HostId>nebula-graph.oss-cn-hangzhou.aliyuncs.com</HostId>
<Key>third-party/3.0/vesoft-third-party-3.0-x86_64-libc-2.17-gcc-9.2.0-abi-11.sh</Key>
</Error>

@yixinglu
Copy link
Contributor

yixinglu commented Dec 27, 2021

I have checked that we haven't compiled the third party for your version 😂,, you can fix it by install gcc 9.3.0 with third-party/install-gcc.sh, and source /opt/vesoft/toolset/gcc/9.3.0/enable. please be free, we'll merge it first.

@Shinji-IkariG Shinji-IkariG merged commit 34cf726 into vesoft-inc:master Dec 27, 2021
@sworduo
Copy link
Contributor Author

sworduo commented Dec 27, 2021

Thx. Since you have merged this pr, it seems that I do not need to push anymore.

@sworduo
Copy link
Contributor Author

sworduo commented Dec 27, 2021

gcc

Hi @yixinglu , when I compile the code, it complains that

wkt/wkt_parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { WKTParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/common/geo/io/wkt/WKTParser.cpp] Error 1
make[1]: *** [src/common/geo/io/CMakeFiles/wkt_parser_target.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
datetime_parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { DatetimeParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/common/time/parser/DatetimeParser.cpp] Error 1
make[1]: *** [src/common/time/parser/CMakeFiles/datetime_parser_target.dir/all] Error 2
[  0%] Building CXX object src/common/memory/test/CMakeFiles/sys_info_read_bm.dir/SysInfoReadBenchmark.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_data.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_metadata.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/raftex_thrift_obj.dir/gen-cpp2/raftex_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/graph_thrift_obj.dir/gen-cpp2/graph_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/raftex_thrift_obj.dir/gen-cpp2/raftex_data.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/graph_thrift_obj.dir/gen-cpp2/graph_data.cpp.o
parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { GraphParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/parser/GraphParser.cpp] Error 1
make[1]: *** [src/parser/CMakeFiles/parser_target.dir/all] Error 2

@Shylock-Hg
Copy link
Contributor

gcc

Hi @yixinglu , when I compile the code, it complains that

wkt/wkt_parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { WKTParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/common/geo/io/wkt/WKTParser.cpp] Error 1
make[1]: *** [src/common/geo/io/CMakeFiles/wkt_parser_target.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
datetime_parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { DatetimeParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/common/time/parser/DatetimeParser.cpp] Error 1
make[1]: *** [src/common/time/parser/CMakeFiles/datetime_parser_target.dir/all] Error 2
[  0%] Building CXX object src/common/memory/test/CMakeFiles/sys_info_read_bm.dir/SysInfoReadBenchmark.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_data.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_metadata.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/raftex_thrift_obj.dir/gen-cpp2/raftex_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/graph_thrift_obj.dir/gen-cpp2/graph_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/raftex_thrift_obj.dir/gen-cpp2/raftex_data.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/graph_thrift_obj.dir/gen-cpp2/graph_data.cpp.o
parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { GraphParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/parser/GraphParser.cpp] Error 1
make[1]: *** [src/parser/CMakeFiles/parser_target.dir/all] Error 2

You need upgrade third-party to 3.0

@sworduo
Copy link
Contributor Author

sworduo commented Dec 28, 2021

gcc

Hi @yixinglu , when I compile the code, it complains that

wkt/wkt_parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { WKTParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/common/geo/io/wkt/WKTParser.cpp] Error 1
make[1]: *** [src/common/geo/io/CMakeFiles/wkt_parser_target.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
datetime_parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { DatetimeParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/common/time/parser/DatetimeParser.cpp] Error 1
make[1]: *** [src/common/time/parser/CMakeFiles/datetime_parser_target.dir/all] Error 2
[  0%] Building CXX object src/common/memory/test/CMakeFiles/sys_info_read_bm.dir/SysInfoReadBenchmark.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_data.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_metadata.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/common_thrift_obj.dir/gen-cpp2/common_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/raftex_thrift_obj.dir/gen-cpp2/raftex_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/graph_thrift_obj.dir/gen-cpp2/graph_constants.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/raftex_thrift_obj.dir/gen-cpp2/raftex_data.cpp.o
[  1%] Building CXX object src/interface/CMakeFiles/graph_thrift_obj.dir/gen-cpp2/graph_data.cpp.o
parser.yy:6.9-24: error: %define variable 'api.parser.class' is not used
 %define api.parser.class { GraphParser }
         ^^^^^^^^^^^^^^^^
make[2]: *** [src/parser/GraphParser.cpp] Error 1
make[1]: *** [src/parser/CMakeFiles/parser_target.dir/all] Error 2

You need upgrade third-party to 3.0

Hi @Shylock-Hg , I fail to upgrade third-party to 3.0. It complains that Downloading vesoft-third-party-3.0-x86_64-libc-2.17-gcc-9.2.0-abi-11.sh failed. If I specify the environment variable -DNEBULA_THIRDPARTY_ROOT=/opt/vesoft/third-party/. It will complain Proxygen doesn't exist. Maybe you can provide a docker for us to compile the code? I find that a docker is provided in 1.2.1 https://docs.nebula-graph.com.cn/1.2.1/manual-CN/3.build-develop-and-administration/1.build/2.build-by-docker/. However, I can't find a docker in the latest manual.

@sworduo sworduo mentioned this pull request Dec 28, 2021
7 tasks
@sworduo sworduo deleted the ExtractFilterExprVisitor branch December 29, 2021 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready for review ready-for-testing PR: ready for the CI test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ExtractFilterExprVisitor implementation bug
10 participants