Skip to content

Commit e4d4cac

Browse files
Sophie-XieHarrisChuSuperYokojievinceczpmango
authored
Cherry pick 3.3 (1020-1021) (#4772)
* logging error if any error in step (#4759) Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com> * fix storage job (#4762) Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com> * fix issue 4765 (#4768) * Avoid full scan of match when there is an Relational In predicate (#4748) * Avoid match full scan when has in predicate fix small fix add test case small change add test cases small fix fmt * small delete Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com> Co-authored-by: Harris.Chu <1726587+HarrisChu@users.noreply.github.com> Co-authored-by: Alex Xing <90179377+SuperYoko@users.noreply.github.com> Co-authored-by: jie.wang <38901892+jievince@users.noreply.github.com> Co-authored-by: kyle.cao <kyle.cao@vesoft.com>
1 parent fe88a7f commit e4d4cac

File tree

11 files changed

+373
-190
lines changed

11 files changed

+373
-190
lines changed

src/common/expression/ContainerExpression.h

+34-14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#ifndef COMMON_EXPRESSION_CONTAINEREXPRESSION_H_
77
#define COMMON_EXPRESSION_CONTAINEREXPRESSION_H_
88

9+
#include "common/base/ObjectPool.h"
10+
#include "common/expression/ConstantExpression.h"
11+
#include "common/expression/ContainerExpression.h"
912
#include "common/expression/Expression.h"
1013

1114
namespace nebula {
@@ -63,7 +66,16 @@ class MapItemList final {
6366
std::vector<Pair> items_;
6467
};
6568

66-
class ListExpression final : public Expression {
69+
class ContainerExpression : public Expression {
70+
public:
71+
virtual const std::vector<Expression *> getKeys() const = 0;
72+
virtual size_t size() const = 0;
73+
74+
protected:
75+
ContainerExpression(ObjectPool *pool, Expression::Kind kind) : Expression(pool, kind) {}
76+
};
77+
78+
class ListExpression final : public ContainerExpression {
6779
public:
6880
ListExpression &operator=(const ListExpression &rhs) = delete;
6981
ListExpression &operator=(ListExpression &&) = delete;
@@ -84,15 +96,15 @@ class ListExpression final : public Expression {
8496
items_[index] = item;
8597
}
8698

87-
std::vector<Expression *> get() {
99+
const std::vector<Expression *> getKeys() const override {
88100
return items_;
89101
}
90102

91103
void setItems(std::vector<Expression *> items) {
92104
items_ = items;
93105
}
94106

95-
size_t size() const {
107+
size_t size() const override {
96108
return items_.size();
97109
}
98110

@@ -116,9 +128,9 @@ class ListExpression final : public Expression {
116128

117129
private:
118130
friend ObjectPool;
119-
explicit ListExpression(ObjectPool *pool) : Expression(pool, Kind::kList) {}
131+
explicit ListExpression(ObjectPool *pool) : ContainerExpression(pool, Kind::kList) {}
120132

121-
ListExpression(ObjectPool *pool, ExpressionList *items) : Expression(pool, Kind::kList) {
133+
ListExpression(ObjectPool *pool, ExpressionList *items) : ContainerExpression(pool, Kind::kList) {
122134
items_ = items->get();
123135
}
124136

@@ -131,7 +143,7 @@ class ListExpression final : public Expression {
131143
Value result_;
132144
};
133145

134-
class SetExpression final : public Expression {
146+
class SetExpression final : public ContainerExpression {
135147
public:
136148
SetExpression &operator=(const SetExpression &rhs) = delete;
137149
SetExpression &operator=(SetExpression &&) = delete;
@@ -152,15 +164,15 @@ class SetExpression final : public Expression {
152164
items_[index] = item;
153165
}
154166

155-
std::vector<Expression *> get() {
167+
const std::vector<Expression *> getKeys() const override {
156168
return items_;
157169
}
158170

159171
void setItems(std::vector<Expression *> items) {
160172
items_ = items;
161173
}
162174

163-
size_t size() const {
175+
size_t size() const override {
164176
return items_.size();
165177
}
166178

@@ -184,9 +196,9 @@ class SetExpression final : public Expression {
184196

185197
private:
186198
friend ObjectPool;
187-
explicit SetExpression(ObjectPool *pool) : Expression(pool, Kind::kSet) {}
199+
explicit SetExpression(ObjectPool *pool) : ContainerExpression(pool, Kind::kSet) {}
188200

189-
SetExpression(ObjectPool *pool, ExpressionList *items) : Expression(pool, Kind::kSet) {
201+
SetExpression(ObjectPool *pool, ExpressionList *items) : ContainerExpression(pool, Kind::kSet) {
190202
items_ = items->get();
191203
}
192204

@@ -199,7 +211,7 @@ class SetExpression final : public Expression {
199211
Value result_;
200212
};
201213

202-
class MapExpression final : public Expression {
214+
class MapExpression final : public ContainerExpression {
203215
public:
204216
MapExpression &operator=(const MapExpression &rhs) = delete;
205217
MapExpression &operator=(MapExpression &&) = delete;
@@ -230,7 +242,15 @@ class MapExpression final : public Expression {
230242
return items_;
231243
}
232244

233-
size_t size() const {
245+
const std::vector<Expression *> getKeys() const override {
246+
std::vector<Expression *> keys;
247+
for (const auto &item : items_) {
248+
keys.emplace_back(ConstantExpression::make(pool_, item.first));
249+
}
250+
return keys;
251+
}
252+
253+
size_t size() const override {
234254
return items_.size();
235255
}
236256

@@ -254,9 +274,9 @@ class MapExpression final : public Expression {
254274

255275
private:
256276
friend ObjectPool;
257-
explicit MapExpression(ObjectPool *pool) : Expression(pool, Kind::kMap) {}
277+
explicit MapExpression(ObjectPool *pool) : ContainerExpression(pool, Kind::kMap) {}
258278

259-
MapExpression(ObjectPool *pool, MapItemList *items) : Expression(pool, Kind::kMap) {
279+
MapExpression(ObjectPool *pool, MapItemList *items) : ContainerExpression(pool, Kind::kMap) {
260280
items_ = items->get();
261281
}
262282

src/graph/planner/ngql/GoPlanner.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ PlanNode* GoPlanner::lastStep(PlanNode* dep, PlanNode* join) {
318318
gd->setInputVar(goCtx_->vidsVar);
319319
gd->setColNames({goCtx_->dstIdColName});
320320
auto* dedup = Dedup::make(qctx, gd);
321+
dedup->setColNames(gd->colNames());
321322
cur = dedup;
322323

323324
if (goCtx_->joinDst) {
@@ -486,6 +487,7 @@ SubPlan GoPlanner::nStepsPlan(SubPlan& startVidPlan) {
486487
gd->setColNames({goCtx_->dstIdColName});
487488
auto* dedup = Dedup::make(qctx, gd);
488489
dedup->setOutputVar(goCtx_->vidsVar);
490+
dedup->setColNames(gd->colNames());
489491
getDst = dedup;
490492

491493
loopBody = getDst;

src/graph/util/ExpressionUtils.cpp

+73-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
#include "graph/util/ExpressionUtils.h"
66

7+
#include "ExpressionUtils.h"
78
#include "common/base/ObjectPool.h"
89
#include "common/expression/ArithmeticExpression.h"
10+
#include "common/expression/ConstantExpression.h"
11+
#include "common/expression/ContainerExpression.h"
912
#include "common/expression/Expression.h"
1013
#include "common/expression/PropertyExpression.h"
1114
#include "common/function/AggFunctionManager.h"
@@ -50,6 +53,30 @@ const Expression *ExpressionUtils::findAny(const Expression *self,
5053
return nullptr;
5154
}
5255

56+
bool ExpressionUtils::findEdgeDstExpr(const Expression *expr) {
57+
auto finder = [](const Expression *e) -> bool {
58+
if (e->kind() == Expression::Kind::kEdgeDst) {
59+
return true;
60+
} else {
61+
auto name = e->toString();
62+
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
63+
if (name == "id($$)") {
64+
return true;
65+
}
66+
}
67+
return false;
68+
};
69+
if (finder(expr)) {
70+
return true;
71+
}
72+
FindVisitor visitor(finder);
73+
const_cast<Expression *>(expr)->accept(&visitor);
74+
if (!visitor.results().empty()) {
75+
return true;
76+
}
77+
return false;
78+
}
79+
5380
// Finds all expressions fit the exprected list
5481
// Returns an empty vector if no expression found
5582
std::vector<const Expression *> ExpressionUtils::collectAll(
@@ -177,6 +204,50 @@ Expression *ExpressionUtils::rewriteParameter(const Expression *expr, QueryConte
177204
return graph::RewriteVisitor::transform(expr, matcher, rewriter);
178205
}
179206

207+
Expression *ExpressionUtils::rewriteInnerInExpr(const Expression *expr) {
208+
auto matcher = [](const Expression *e) -> bool {
209+
if (e->kind() != Expression::Kind::kRelIn) {
210+
return false;
211+
}
212+
auto rhs = static_cast<const RelationalExpression *>(e)->right();
213+
if (rhs->kind() != Expression::Kind::kList && rhs->kind() != Expression::Kind::kSet) {
214+
return false;
215+
}
216+
auto items = static_cast<const ContainerExpression *>(rhs)->getKeys();
217+
for (const auto *item : items) {
218+
if (!ExpressionUtils::isEvaluableExpr(item)) {
219+
return false;
220+
}
221+
}
222+
return true;
223+
};
224+
auto rewriter = [](const Expression *e) -> Expression * {
225+
DCHECK_EQ(e->kind(), Expression::Kind::kRelIn);
226+
const auto re = static_cast<const RelationalExpression *>(e);
227+
auto lhs = re->left();
228+
auto rhs = re->right();
229+
DCHECK(rhs->kind() == Expression::Kind::kList || rhs->kind() == Expression::Kind::kSet);
230+
auto ce = static_cast<const ContainerExpression *>(rhs);
231+
auto pool = e->getObjPool();
232+
auto *rewrittenExpr = LogicalExpression::makeOr(pool);
233+
// Pointer to a single-level expression
234+
Expression *singleExpr = nullptr;
235+
auto items = ce->getKeys();
236+
for (auto i = 0u; i < items.size(); ++i) {
237+
auto *ee = RelationalExpression::makeEQ(pool, lhs->clone(), items[i]->clone());
238+
rewrittenExpr->addOperand(ee);
239+
if (i == 0) {
240+
singleExpr = ee;
241+
} else {
242+
singleExpr = nullptr;
243+
}
244+
}
245+
return singleExpr ? singleExpr : rewrittenExpr;
246+
};
247+
248+
return graph::RewriteVisitor::transform(expr, matcher, rewriter);
249+
}
250+
180251
Expression *ExpressionUtils::rewriteAgg2VarProp(const Expression *expr) {
181252
ObjectPool *pool = expr->getObjPool();
182253
auto matcher = [](const Expression *e) -> bool {
@@ -344,10 +415,10 @@ std::vector<Expression *> ExpressionUtils::getContainerExprOperands(const Expres
344415
std::vector<Expression *> containerOperands;
345416
switch (containerExpr->kind()) {
346417
case Expression::Kind::kList:
347-
containerOperands = static_cast<ListExpression *>(containerExpr)->get();
418+
containerOperands = static_cast<ListExpression *>(containerExpr)->getKeys();
348419
break;
349420
case Expression::Kind::kSet: {
350-
containerOperands = static_cast<SetExpression *>(containerExpr)->get();
421+
containerOperands = static_cast<SetExpression *>(containerExpr)->getKeys();
351422
break;
352423
}
353424
case Expression::Kind::kMap: {

src/graph/util/ExpressionUtils.h

+6
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class ExpressionUtils {
8383
// Rewrites ParameterExpression to ConstantExpression
8484
static Expression* rewriteParameter(const Expression* expr, QueryContext* qctx);
8585

86+
// Rewrite RelInExpr with only one operand in expression tree
87+
static Expression* rewriteInnerInExpr(const Expression* expr);
88+
8689
// Rewrites relational expression, gather all evaluable expressions in the left operands and move
8790
// them to the right
8891
static Expression* rewriteRelExpr(const Expression* expr);
@@ -193,6 +196,9 @@ class ExpressionUtils {
193196
// Checks if expr contains function call expression that generate a random value
194197
static bool findInnerRandFunction(const Expression* expr);
195198

199+
// Checks if expr contains function EdgeDst expr or id($$) expr
200+
static bool findEdgeDstExpr(const Expression* expr);
201+
196202
// ** Loop node condition **
197203
// Generates an expression that is used as the condition of loop node:
198204
// ++loopSteps <= steps

src/graph/validator/GoValidator.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ Status GoValidator::validateWhere(WhereClause* where) {
9999
return Status::SemanticError(ss.str());
100100
}
101101

102-
goCtx_->filter = rewriteVertexEdge2EdgeProp(filter);
103102
NG_RETURN_IF_ERROR(deduceProps(filter, goCtx_->exprProps, &tagIds_, &goCtx_->over.edgeTypes));
103+
goCtx_->filter = filter;
104104
return Status::OK();
105105
}
106106

@@ -311,6 +311,15 @@ bool GoValidator::isSimpleCase() {
311311
}
312312
if (exprProps.hasInputVarProperty()) return false;
313313

314+
// Check filter clause
315+
// Because GetDstBySrc doesn't support filter push down,
316+
// so we don't optimize such case.
317+
if (goCtx_->filter) {
318+
if (ExpressionUtils::findEdgeDstExpr(goCtx_->filter)) {
319+
return false;
320+
}
321+
}
322+
314323
// Check yield clause
315324
if (!goCtx_->distinct) return false;
316325
bool atLeastOneDstId = false;

src/graph/validator/MatchValidator.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ Status MatchValidator::buildEdgeInfo(const MatchPath *path,
303303
// Rewrite expression to fit semantic, check type and check used aliases.
304304
Status MatchValidator::validateFilter(const Expression *filter,
305305
WhereClauseContext &whereClauseCtx) {
306-
auto transformRes = ExpressionUtils::filterTransform(filter);
306+
auto *newFilter = graph::ExpressionUtils::rewriteInnerInExpr(filter);
307+
auto transformRes = ExpressionUtils::filterTransform(newFilter);
307308
NG_RETURN_IF_ERROR(transformRes);
308309
// rewrite Attribute to LabelTagProperty
309310
whereClauseCtx.filter = ExpressionUtils::rewriteAttr2LabelTagProp(

src/meta/processors/job/StorageJobExecutor.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class StorageJobExecutor : public JobExecutor {
8484
}
8585

8686
JobDescription getJobDescription() override {
87-
JobDescription ret;
87+
JobDescription ret{space_, jobId_, cpp2::JobType::UNKNOWN};
8888
return ret;
8989
}
9090

tests/conftest.py

+26-22
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,36 @@ def pytest_runtest_logreport(report):
5050

5151
def pytest_addoption(parser):
5252
for config in all_configs:
53-
parser.addoption(config,
54-
dest=all_configs[config][0],
55-
default=all_configs[config][1],
56-
help=all_configs[config][2])
53+
parser.addoption(
54+
config,
55+
dest=all_configs[config][0],
56+
default=all_configs[config][1],
57+
help=all_configs[config][2],
58+
)
5759

58-
parser.addoption("--build_dir",
59-
dest="build_dir",
60-
default=BUILD_DIR,
61-
help="NebulaGraph CMake build directory")
62-
parser.addoption("--src_dir",
63-
dest="src_dir",
64-
default=NEBULA_HOME,
65-
help="NebulaGraph workspace")
60+
parser.addoption(
61+
"--build_dir",
62+
dest="build_dir",
63+
default=BUILD_DIR,
64+
help="NebulaGraph CMake build directory",
65+
)
66+
parser.addoption(
67+
"--src_dir", dest="src_dir", default=NEBULA_HOME, help="NebulaGraph workspace"
68+
)
6669

6770

6871
def pytest_bdd_step_error(request, feature, scenario, step, step_func, step_func_args):
69-
logging.info("=== more error information ===")
70-
logging.info("feature is {}".format(feature.filename))
71-
logging.info("step line number is {}".format(step.line_number))
72-
logging.info("step name is {}".format(step.name))
73-
if step_func_args.get("graph_spaces") is not None:
72+
logging.error("Location: {}:{}".format(feature.filename, step.line_number))
73+
logging.error("Step: {}".format(step.name))
74+
graph_spaces = None
75+
if graph_spaces is None and step_func_args.get("graph_spaces") is not None:
7476
graph_spaces = step_func_args.get("graph_spaces")
75-
if graph_spaces.get("space_desc") is not None:
76-
logging.info("error space is {}".format(
77-
graph_spaces.get("space_desc")))
77+
78+
if graph_spaces is None and step_func_args.get("exec_ctx") is not None:
79+
graph_spaces = step_func_args.get("exec_ctx")
80+
81+
if graph_spaces is not None and graph_spaces.get("space_desc") is not None:
82+
logging.error("Space: {}".format(graph_spaces.get("space_desc")))
7883

7984

8085
def pytest_configure(config):
@@ -125,8 +130,7 @@ def get_ssl_config_from_tmp():
125130

126131
@pytest.fixture(scope="class")
127132
def class_fixture_variables():
128-
"""save class scope fixture, used for session update.
129-
"""
133+
"""save class scope fixture, used for session update."""
130134
# cluster is the instance of NebulaService
131135
# current_session is the session currently using
132136
# sessions is a list of all sessions in the cluster

0 commit comments

Comments
 (0)