@@ -171,29 +171,43 @@ Status LookupExecutor::optimize() {
171
171
return status;
172
172
}
173
173
174
- Status LookupExecutor::traversalExpr (const Expression *expr) {
174
+ Status LookupExecutor::traversalExpr (const Expression *expr, const meta::SchemaProviderIf* schema ) {
175
175
switch (expr->kind ()) {
176
176
case nebula::Expression::kLogical : {
177
+ Status ret = Status::OK ();
177
178
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 ());
180
184
}
181
185
auto * left = lExpr->left ();
182
- traversalExpr (left);
186
+ ret = traversalExpr (left, schema);
187
+ if (!ret.ok ()) {
188
+ return ret;
189
+ }
183
190
auto * right = lExpr->right ();
184
- traversalExpr (right);
191
+ ret = traversalExpr (right, schema);
192
+ if (!ret.ok ()) {
193
+ return ret;
194
+ }
185
195
break ;
186
196
}
187
197
case nebula::Expression::kRelational : {
188
198
std::string prop;
189
199
VariantType v;
190
200
auto * rExpr = dynamic_cast <const RelationalExpression*>(expr);
201
+ auto ret = relationalExprCheck (rExpr->op ());
202
+ if (!ret.ok ()) {
203
+ return ret;
204
+ }
191
205
auto * left = rExpr->left ();
192
206
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 ) {
197
211
auto * aExpr = dynamic_cast <const AliasPropertyExpression*>(left);
198
212
auto st = checkAliasProperty (aExpr);
199
213
if (!st.ok ()) {
@@ -213,15 +227,19 @@ Status LookupExecutor::traversalExpr(const Expression *expr) {
213
227
return Status::SyntaxError (" Unsupported expression :%s" ,
214
228
rExpr->toString ().c_str ());
215
229
}
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
+ }
216
239
break ;
217
240
}
218
241
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" );
225
243
}
226
244
default : {
227
245
return Status::SyntaxError (" Syntax error : %s" , expr->toString ().c_str ());
@@ -231,7 +249,15 @@ Status LookupExecutor::traversalExpr(const Expression *expr) {
231
249
}
232
250
233
251
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 ());
235
261
if (!status.ok ()) {
236
262
return status;
237
263
}
@@ -826,5 +852,35 @@ bool LookupExecutor::processFinalVertexResult(RpcResponse &rpcResp,
826
852
return true ;
827
853
}
828
854
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
+ }
829
885
} // namespace graph
830
886
} // namespace nebula
0 commit comments