Skip to content

Commit f1a11c1

Browse files
Disable index range scan of string data type in graph layer (vesoft-inc#2283)
* Disable string range scan in graph lyear * rename mothod dataTypeCheckForRange to supportedDataTypeForRange * fixed typo error * Does not support left expr and right expr are both kAliasProp
1 parent 9603050 commit f1a11c1

File tree

3 files changed

+79
-20
lines changed

3 files changed

+79
-20
lines changed

src/graph/LookupExecutor.cpp

+72-16
Original file line numberDiff line numberDiff line change
@@ -171,29 +171,43 @@ Status LookupExecutor::optimize() {
171171
return status;
172172
}
173173

174-
Status LookupExecutor::traversalExpr(const Expression *expr) {
174+
Status LookupExecutor::traversalExpr(const Expression *expr, const meta::SchemaProviderIf* schema) {
175175
switch (expr->kind()) {
176176
case nebula::Expression::kLogical : {
177+
Status ret = Status::OK();
177178
auto* lExpr = dynamic_cast<const LogicalExpression*>(expr);
178-
if (lExpr->op() == LogicalExpression::Operator::XOR) {
179-
return Status::SyntaxError("Syntax error : %s", lExpr->toString().c_str());
179+
if (lExpr->op() == LogicalExpression::Operator::XOR ||
180+
lExpr->op() == LogicalExpression::Operator::OR) {
181+
return Status::SyntaxError("OR and XOR are not supported "
182+
"in lookup where clause :%s",
183+
lExpr->toString().c_str());
180184
}
181185
auto* left = lExpr->left();
182-
traversalExpr(left);
186+
ret = traversalExpr(left, schema);
187+
if (!ret.ok()) {
188+
return ret;
189+
}
183190
auto* right = lExpr->right();
184-
traversalExpr(right);
191+
ret = traversalExpr(right, schema);
192+
if (!ret.ok()) {
193+
return ret;
194+
}
185195
break;
186196
}
187197
case nebula::Expression::kRelational : {
188198
std::string prop;
189199
VariantType v;
190200
auto* rExpr = dynamic_cast<const RelationalExpression*>(expr);
201+
auto ret = relationalExprCheck(rExpr->op());
202+
if (!ret.ok()) {
203+
return ret;
204+
}
191205
auto* left = rExpr->left();
192206
auto* right = rExpr->right();
193-
/**
194-
* TODO (sky) : Does not support left expr and right expr are both kAliasProp.
195-
*/
196-
if (left->kind() == nebula::Expression::kAliasProp) {
207+
if (left->kind() == nebula::Expression::kAliasProp &&
208+
right->kind() == nebula::Expression::kAliasProp) {
209+
return Status::SyntaxError("Does not support left and right are both property");
210+
} else if (left->kind() == nebula::Expression::kAliasProp) {
197211
auto* aExpr = dynamic_cast<const AliasPropertyExpression*>(left);
198212
auto st = checkAliasProperty(aExpr);
199213
if (!st.ok()) {
@@ -213,15 +227,19 @@ Status LookupExecutor::traversalExpr(const Expression *expr) {
213227
return Status::SyntaxError("Unsupported expression :%s",
214228
rExpr->toString().c_str());
215229
}
230+
231+
if (rExpr->op() != RelationalExpression::Operator::EQ &&
232+
rExpr->op() != RelationalExpression::Operator::NE) {
233+
auto type = schema->getFieldType(prop).type;
234+
if (!supportedDataTypeForRange(type)) {
235+
return Status::SyntaxError("Data type of field %s not support range scan",
236+
prop.c_str());
237+
}
238+
}
216239
break;
217240
}
218241
case nebula::Expression::kFunctionCall : {
219-
auto* fExpr = dynamic_cast<const FunctionCallExpression*>(expr);
220-
auto* name = fExpr->name();
221-
if (*name == "udf_is_in") {
222-
return Status::SyntaxError("Unsupported function : %s", name->c_str());
223-
}
224-
break;
242+
return Status::SyntaxError("Function expressions are not supported yet");
225243
}
226244
default : {
227245
return Status::SyntaxError("Syntax error : %s", expr->toString().c_str());
@@ -231,7 +249,15 @@ Status LookupExecutor::traversalExpr(const Expression *expr) {
231249
}
232250

233251
Status LookupExecutor::checkFilter() {
234-
auto status = traversalExpr(sentence_->whereClause()->filter());
252+
auto *sm = ectx()->schemaManager();
253+
auto schema = isEdge_
254+
? sm->getEdgeSchema(spaceId_, tagOrEdge_)
255+
: sm->getTagSchema(spaceId_, tagOrEdge_);
256+
if (schema == nullptr) {
257+
return Status::Error("No schema found %s", from_->c_str());
258+
}
259+
260+
auto status = traversalExpr(sentence_->whereClause()->filter(), schema.get());
235261
if (!status.ok()) {
236262
return status;
237263
}
@@ -826,5 +852,35 @@ bool LookupExecutor::processFinalVertexResult(RpcResponse &rpcResp,
826852
return true;
827853
}
828854

855+
Status LookupExecutor::relationalExprCheck(RelationalExpression::Operator op) const {
856+
// Compile will fail after added new relational operations.
857+
// Need to consider the logic in method 'traversalExpr' after new relational operation added.
858+
switch (op) {
859+
case RelationalExpression::Operator::EQ :
860+
case RelationalExpression::Operator::GE :
861+
case RelationalExpression::Operator::GT :
862+
case RelationalExpression::Operator::LE :
863+
case RelationalExpression::Operator::LT :
864+
case RelationalExpression::Operator::NE : {
865+
return Status::OK();
866+
}
867+
case RelationalExpression::Operator::CONTAINS : {
868+
return Status::SyntaxError("Unsupported 'CONTAINS' in where clause");
869+
}
870+
}
871+
return Status::OK();
872+
}
873+
874+
bool LookupExecutor::supportedDataTypeForRange(nebula::cpp2::SupportedType type) const {
875+
switch (type) {
876+
case nebula::cpp2::SupportedType::INT:
877+
case nebula::cpp2::SupportedType::DOUBLE:
878+
case nebula::cpp2::SupportedType::FLOAT:
879+
case nebula::cpp2::SupportedType::TIMESTAMP:
880+
return true;
881+
default:
882+
return false;
883+
}
884+
}
829885
} // namespace graph
830886
} // namespace nebula

src/graph/LookupExecutor.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class LookupExecutor final : public TraverseExecutor {
4949

5050
Status optimize();
5151

52-
Status traversalExpr(const Expression *expr);
52+
Status traversalExpr(const Expression *expr, const meta::SchemaProviderIf* schema);
5353

5454
Status checkFilter();
5555

@@ -85,6 +85,9 @@ class LookupExecutor final : public TraverseExecutor {
8585

8686
bool processFinalVertexResult(RpcResponse &rpcResp, const Callback& cb) const;
8787

88+
Status relationalExprCheck(RelationalExpression::Operator op) const;
89+
90+
bool supportedDataTypeForRange(nebula::cpp2::SupportedType type) const;
8891

8992
private:
9093
using FilterItem = std::pair<std::string, RelationalExpression::Operator>;

src/graph/test/LookupTest.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ TEST_F(LookupTest, VertexConditionScan) {
236236
auto query = "LOOKUP ON lookup_tag_2 WHERE lookup_tag_2.col2 == 100 "
237237
"OR lookup_tag_2.col2 == 200";
238238
auto code = client_->execute(query, resp);
239-
ASSERT_EQ(cpp2::ErrorCode::E_EXECUTION_ERROR, code);
239+
ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
240240
}
241241
{
242242
cpp2::ExecutionResponse resp;
@@ -398,7 +398,7 @@ TEST_F(LookupTest, EdgeConditionScan) {
398398
auto query = "LOOKUP ON lookup_edge_2 WHERE lookup_edge_2.col2 == 100 "
399399
"OR lookup_edge_2.col2 == 200";
400400
auto code = client_->execute(query, resp);
401-
ASSERT_EQ(cpp2::ErrorCode::E_EXECUTION_ERROR, code);
401+
ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
402402
}
403403
{
404404
cpp2::ExecutionResponse resp;
@@ -660,7 +660,7 @@ TEST_F(LookupTest, FunctionExprTest) {
660660
cpp2::ExecutionResponse resp;
661661
auto query = "LOOKUP ON lookup_tag_2 WHERE lookup_tag_2.col2 != lookup_tag_2.col3";
662662
auto code = client_->execute(query, resp);
663-
ASSERT_EQ(cpp2::ErrorCode::E_EXECUTION_ERROR, code);
663+
ASSERT_EQ(cpp2::ErrorCode::E_SYNTAX_ERROR, code);
664664
}
665665
{
666666
cpp2::ExecutionResponse resp;

0 commit comments

Comments
 (0)