1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "query_expression.h"
16 #include "log_print.h"
17 #include "schema_utils.h"
18 #include "db_errno.h"
19
20 namespace DistributedDB {
21 namespace {
22 const int MAX_OPR_TIMES = 256;
23 } // namespace
24
AssemblyQueryInfo(const QueryObjType queryOperType,const std::string & field,const QueryValueType type,const std::vector<FieldValue> & values,bool isNeedFieldPath=true)25 void QueryExpression::AssemblyQueryInfo(const QueryObjType queryOperType, const std::string& field,
26 const QueryValueType type, const std::vector<FieldValue> &values, bool isNeedFieldPath = true)
27 {
28 if (useFromTable_) {
29 expressions_[fromTable_].AssemblyQueryInfo(queryOperType, field, type, values, isNeedFieldPath);
30 SetNotSupportIfNeed(queryOperType);
31 return;
32 }
33 if (!tables_.empty()) {
34 validStatus_ = -E_NOT_SUPPORT;
35 }
36 if (queryInfo_.size() > MAX_OPR_TIMES) {
37 SetErrFlag(false);
38 LOGE("Operate too much times!");
39 return;
40 }
41
42 if (!GetErrFlag()) {
43 LOGE("Illegal data node!");
44 return;
45 }
46
47 FieldPath outPath;
48 if (isNeedFieldPath) {
49 if (SchemaUtils::ParseAndCheckFieldPath(field, outPath) != E_OK) {
50 SetErrFlag(false);
51 LOGE("Field path illegal!");
52 return;
53 }
54 }
55 std::string formatedField;
56 if (isTableNameSpecified_) { // remove '$.' prefix in relational query
57 for (auto it = outPath.begin(); it < outPath.end(); ++it) {
58 if (it != outPath.begin()) {
59 formatedField += ".";
60 }
61 formatedField += *it;
62 }
63 } else {
64 formatedField = field;
65 }
66 if (!queryInfo_.empty() && queryInfo_.back().operFlag == queryOperType) {
67 validStatus_ = -E_INVALID_ARGS;
68 }
69 queryInfo_.emplace_back(QueryObjNode{queryOperType, formatedField, type, values});
70 }
71
QueryExpression()72 QueryExpression::QueryExpression()
73 : errFlag_(true),
74 tableName_("sync_data"), // default kv type store table name
75 isTableNameSpecified_(false) // default no specify for kv type store table name
76 {}
77
EqualTo(const std::string & field,const QueryValueType type,const FieldValue & value)78 void QueryExpression::EqualTo(const std::string& field, const QueryValueType type, const FieldValue &value)
79 {
80 std::vector<FieldValue> fieldValues{value};
81 AssemblyQueryInfo(QueryObjType::EQUALTO, field, type, fieldValues);
82 }
83
NotEqualTo(const std::string & field,const QueryValueType type,const FieldValue & value)84 void QueryExpression::NotEqualTo(const std::string& field, const QueryValueType type, const FieldValue &value)
85 {
86 std::vector<FieldValue> fieldValues{value};
87 AssemblyQueryInfo(QueryObjType::NOT_EQUALTO, field, type, fieldValues);
88 }
89
GreaterThan(const std::string & field,const QueryValueType type,const FieldValue & value)90 void QueryExpression::GreaterThan(const std::string& field, const QueryValueType type, const FieldValue &value)
91 {
92 if (type == QueryValueType::VALUE_TYPE_BOOL) {
93 LOGD("Prohibit the use of bool for comparison!");
94 SetErrFlag(false);
95 }
96 std::vector<FieldValue> fieldValues{value};
97 AssemblyQueryInfo(QueryObjType::GREATER_THAN, field, type, fieldValues);
98 }
99
LessThan(const std::string & field,const QueryValueType type,const FieldValue & value)100 void QueryExpression::LessThan(const std::string& field, const QueryValueType type, const FieldValue &value)
101 {
102 if (type == QueryValueType::VALUE_TYPE_BOOL) {
103 LOGD("Prohibit the use of bool for comparison!");
104 SetErrFlag(false);
105 }
106 std::vector<FieldValue> fieldValues{value};
107 AssemblyQueryInfo(QueryObjType::LESS_THAN, field, type, fieldValues);
108 }
109
GreaterThanOrEqualTo(const std::string & field,const QueryValueType type,const FieldValue & value)110 void QueryExpression::GreaterThanOrEqualTo(const std::string& field, const QueryValueType type, const FieldValue &value)
111 {
112 if (type == QueryValueType::VALUE_TYPE_BOOL) {
113 LOGD("Prohibit the use of bool for comparison!");
114 SetErrFlag(false);
115 }
116 std::vector<FieldValue> fieldValues{value};
117 AssemblyQueryInfo(QueryObjType::GREATER_THAN_OR_EQUALTO, field, type, fieldValues);
118 }
119
LessThanOrEqualTo(const std::string & field,const QueryValueType type,const FieldValue & value)120 void QueryExpression::LessThanOrEqualTo(const std::string& field, const QueryValueType type, const FieldValue &value)
121 {
122 if (type == QueryValueType::VALUE_TYPE_BOOL) {
123 LOGD("Prohibit the use of bool for comparison!");
124 SetErrFlag(false);
125 }
126 std::vector<FieldValue> fieldValues{value};
127 AssemblyQueryInfo(QueryObjType::LESS_THAN_OR_EQUALTO, field, type, fieldValues);
128 }
129
OrderBy(const std::string & field,bool isAsc)130 void QueryExpression::OrderBy(const std::string& field, bool isAsc)
131 {
132 FieldValue fieldValue;
133 fieldValue.boolValue = isAsc;
134 std::vector<FieldValue> fieldValues{fieldValue};
135 AssemblyQueryInfo(QueryObjType::ORDERBY, field, QueryValueType::VALUE_TYPE_BOOL, fieldValues);
136 }
137
Like(const std::string & field,const std::string & value)138 void QueryExpression::Like(const std::string& field, const std::string &value)
139 {
140 FieldValue fieldValue;
141 fieldValue.stringValue = value;
142 std::vector<FieldValue> fieldValues{fieldValue};
143 AssemblyQueryInfo(QueryObjType::LIKE, field, QueryValueType::VALUE_TYPE_STRING, fieldValues);
144 }
145
NotLike(const std::string & field,const std::string & value)146 void QueryExpression::NotLike(const std::string& field, const std::string &value)
147 {
148 FieldValue fieldValue;
149 fieldValue.stringValue = value;
150 std::vector<FieldValue> fieldValues{fieldValue};
151 AssemblyQueryInfo(QueryObjType::NOT_LIKE, field, QueryValueType::VALUE_TYPE_STRING, fieldValues);
152 }
153
Limit(int number,int offset)154 void QueryExpression::Limit(int number, int offset)
155 {
156 FieldValue fieldNumber;
157 fieldNumber.integerValue = number;
158 FieldValue fieldOffset;
159 fieldOffset.integerValue = offset;
160 std::vector<FieldValue> fieldValues{fieldNumber, fieldOffset};
161 AssemblyQueryInfo(QueryObjType::LIMIT, std::string(), QueryValueType::VALUE_TYPE_INTEGER, fieldValues, false);
162 }
163
IsNull(const std::string & field)164 void QueryExpression::IsNull(const std::string& field)
165 {
166 AssemblyQueryInfo(QueryObjType::IS_NULL, field, QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>());
167 }
168
IsNotNull(const std::string & field)169 void QueryExpression::IsNotNull(const std::string& field)
170 {
171 AssemblyQueryInfo(QueryObjType::IS_NOT_NULL, field, QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>());
172 }
173
In(const std::string & field,const QueryValueType type,const std::vector<FieldValue> & values)174 void QueryExpression::In(const std::string& field, const QueryValueType type, const std::vector<FieldValue> &values)
175 {
176 AssemblyQueryInfo(QueryObjType::IN, field, type, values);
177 }
178
NotIn(const std::string & field,const QueryValueType type,const std::vector<FieldValue> & values)179 void QueryExpression::NotIn(const std::string& field, const QueryValueType type, const std::vector<FieldValue> &values)
180 {
181 AssemblyQueryInfo(QueryObjType::NOT_IN, field, type, values);
182 }
183
And()184 void QueryExpression::And()
185 {
186 AssemblyQueryInfo(QueryObjType::AND, std::string(), QueryValueType::VALUE_TYPE_NULL,
187 std::vector<FieldValue>(), false);
188 }
189
Or()190 void QueryExpression::Or()
191 {
192 AssemblyQueryInfo(QueryObjType::OR, std::string(), QueryValueType::VALUE_TYPE_NULL,
193 std::vector<FieldValue>(), false);
194 }
195
QueryByPrefixKey(const std::vector<uint8_t> & key)196 void QueryExpression::QueryByPrefixKey(const std::vector<uint8_t> &key)
197 {
198 if (useFromTable_) {
199 expressions_[fromTable_].QueryByPrefixKey(key);
200 validStatus_ = -E_NOT_SUPPORT;
201 return;
202 }
203 SetNotSupportIfFromTables();
204 queryInfo_.emplace_front(QueryObjNode{QueryObjType::QUERY_BY_KEY_PREFIX, std::string(),
205 QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>()});
206 prefixKey_ = key;
207 }
208
QueryByKeyRange(const std::vector<uint8_t> & keyBegin,const std::vector<uint8_t> & keyEnd)209 void QueryExpression::QueryByKeyRange(const std::vector<uint8_t> &keyBegin, const std::vector<uint8_t> &keyEnd)
210 {
211 if (useFromTable_) {
212 expressions_[fromTable_].QueryByKeyRange(keyBegin, keyEnd);
213 validStatus_ = -E_NOT_SUPPORT;
214 return;
215 }
216 SetNotSupportIfFromTables();
217 queryInfo_.emplace_front(QueryObjNode{QueryObjType::KEY_RANGE, std::string(),
218 QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>()});
219 beginKey_ = keyBegin;
220 endKey_ = keyEnd;
221 }
222
QueryBySuggestIndex(const std::string & indexName)223 void QueryExpression::QueryBySuggestIndex(const std::string &indexName)
224 {
225 if (useFromTable_) {
226 expressions_[fromTable_].QueryBySuggestIndex(indexName);
227 validStatus_ = -E_NOT_SUPPORT;
228 return;
229 }
230 SetNotSupportIfFromTables();
231 queryInfo_.emplace_back(QueryObjNode{QueryObjType::SUGGEST_INDEX, indexName,
232 QueryValueType::VALUE_TYPE_STRING, std::vector<FieldValue>()});
233 suggestIndex_ = indexName;
234 }
235
InKeys(const std::set<Key> & keys)236 void QueryExpression::InKeys(const std::set<Key> &keys)
237 {
238 if (useFromTable_) {
239 expressions_[fromTable_].InKeys(keys);
240 validStatus_ = -E_NOT_SUPPORT;
241 return;
242 }
243 SetNotSupportIfFromTables();
244 queryInfo_.emplace_front(QueryObjNode{QueryObjType::IN_KEYS, std::string(), QueryValueType::VALUE_TYPE_NULL,
245 std::vector<FieldValue>()});
246 keys_ = keys;
247 }
248
GetQueryExpression()249 const std::list<QueryObjNode> &QueryExpression::GetQueryExpression()
250 {
251 if (!GetErrFlag()) {
252 queryInfo_.clear();
253 queryInfo_.emplace_back(QueryObjNode{QueryObjType::OPER_ILLEGAL});
254 LOGE("Query operate illegal!");
255 }
256 return queryInfo_;
257 }
258
GetBeginKey() const259 std::vector<uint8_t> QueryExpression::GetBeginKey() const
260 {
261 return beginKey_;
262 }
263
GetEndKey() const264 std::vector<uint8_t> QueryExpression::GetEndKey() const
265 {
266 return endKey_;
267 }
268
GetPreFixKey() const269 std::vector<uint8_t> QueryExpression::GetPreFixKey() const
270 {
271 return prefixKey_;
272 }
273
SetTableName(const std::string & tableName)274 void QueryExpression::SetTableName(const std::string &tableName)
275 {
276 tableName_ = tableName;
277 isTableNameSpecified_ = true;
278 }
279
GetTableName()280 const std::string &QueryExpression::GetTableName()
281 {
282 return tableName_;
283 }
284
IsTableNameSpecified() const285 bool QueryExpression::IsTableNameSpecified() const
286 {
287 return isTableNameSpecified_;
288 }
289
GetSuggestIndex() const290 std::string QueryExpression::GetSuggestIndex() const
291 {
292 return suggestIndex_;
293 }
294
GetKeys() const295 const std::set<Key> &QueryExpression::GetKeys() const
296 {
297 return keys_;
298 }
299
BeginGroup()300 void QueryExpression::BeginGroup()
301 {
302 if (useFromTable_) {
303 expressions_[fromTable_].BeginGroup();
304 return;
305 }
306 SetNotSupportIfFromTables();
307 queryInfo_.emplace_back(QueryObjNode{QueryObjType::BEGIN_GROUP, std::string(),
308 QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>()});
309 }
310
EndGroup()311 void QueryExpression::EndGroup()
312 {
313 if (useFromTable_) {
314 expressions_[fromTable_].EndGroup();
315 return;
316 }
317 SetNotSupportIfFromTables();
318 queryInfo_.emplace_back(QueryObjNode{QueryObjType::END_GROUP, std::string(),
319 QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>()});
320 }
321
Reset()322 void QueryExpression::Reset()
323 {
324 errFlag_ = true;
325 queryInfo_.clear();
326 prefixKey_.clear();
327 prefixKey_.shrink_to_fit();
328 suggestIndex_.clear();
329 keys_.clear();
330 }
331
SetErrFlag(bool flag)332 void QueryExpression::SetErrFlag(bool flag)
333 {
334 errFlag_ = flag;
335 }
336
GetErrFlag()337 bool QueryExpression::GetErrFlag()
338 {
339 return errFlag_;
340 }
341
GetSortType() const342 int QueryExpression::GetSortType() const
343 {
344 return sortType_;
345 }
346
SetSortType(bool isAsc)347 void QueryExpression::SetSortType(bool isAsc)
348 {
349 if (useFromTable_) {
350 expressions_[fromTable_].SetSortType(isAsc);
351 validStatus_ = -E_NOT_SUPPORT;
352 return;
353 }
354 SetNotSupportIfFromTables();
355 WriteTimeSort sortType = isAsc ? WriteTimeSort::TIMESTAMP_ASC : WriteTimeSort::TIMESTAMP_DESC;
356 sortType_ = static_cast<int>(sortType);
357 }
358
GetTables()359 std::vector<std::string> QueryExpression::GetTables()
360 {
361 return tables_;
362 }
363
SetTables(const std::vector<std::string> & tableNames)364 void QueryExpression::SetTables(const std::vector<std::string> &tableNames)
365 {
366 // filter same table
367 std::vector<std::string> syncTable;
368 std::set<std::string> addTable;
369 for (const auto &table: tableNames) {
370 if (addTable.find(table) == addTable.end()) {
371 addTable.insert(table);
372 syncTable.push_back(table);
373 }
374 }
375 tables_ = syncTable;
376 if (useFromTable_) {
377 validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_NOT_SUPPORT;
378 }
379 SetNotSupportIfCondition();
380 }
381
From(const std::string & tableName)382 void QueryExpression::From(const std::string &tableName)
383 {
384 useFromTable_ = true;
385 fromTable_ = tableName;
386 for (const auto &item: tableSequence_) {
387 if (item == tableName) {
388 return;
389 }
390 }
391 tableSequence_.push_back(fromTable_);
392 expressions_[fromTable_].SetTableName(fromTable_);
393 if (tableName.empty()) {
394 validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_INVALID_ARGS;
395 } else if (!tables_.empty()) {
396 validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_NOT_SUPPORT;
397 }
398 SetNotSupportIfFromTables();
399 SetNotSupportIfCondition();
400 }
401
GetExpressionStatus() const402 int QueryExpression::GetExpressionStatus() const
403 {
404 return validStatus_;
405 }
406
GetQueryExpressions() const407 std::vector<QueryExpression> QueryExpression::GetQueryExpressions() const
408 {
409 if (!useFromTable_) {
410 return {};
411 }
412 std::vector<QueryExpression> res;
413 for (const auto &item : tableSequence_) {
414 res.push_back(expressions_.at(item));
415 }
416 return res;
417 }
418
SetNotSupportIfFromTables()419 void QueryExpression::SetNotSupportIfFromTables()
420 {
421 if (validStatus_ != E_OK) {
422 return;
423 }
424 if (!tables_.empty()) {
425 validStatus_ = -E_NOT_SUPPORT;
426 }
427 }
428
SetNotSupportIfCondition()429 void QueryExpression::SetNotSupportIfCondition()
430 {
431 if (validStatus_ != E_OK) {
432 return;
433 }
434 if (!queryInfo_.empty()) {
435 validStatus_ = -E_NOT_SUPPORT;
436 }
437 }
438
SetNotSupportIfNeed(QueryObjType type)439 void QueryExpression::SetNotSupportIfNeed(QueryObjType type)
440 {
441 if (validStatus_ != E_OK) {
442 return;
443 }
444 if (type != QueryObjType::IN && type != QueryObjType::EQUALTO && type != QueryObjType::AND &&
445 type != QueryObjType::OR) {
446 validStatus_ = -E_NOT_SUPPORT;
447 }
448 if (validStatus_ != E_OK) {
449 return;
450 }
451 for (const auto &item: queryInfo_) {
452 if (((item.operFlag == QueryObjType::EQUALTO) && (type == QueryObjType::IN)) ||
453 ((item.operFlag == QueryObjType::IN) && (type == QueryObjType::EQUALTO))) {
454 validStatus_ = -E_NOT_SUPPORT;
455 LOGW("[Query] Not support use in and equal to at same time when use from table");
456 break;
457 }
458 }
459 }
460
RangeParamCheck() const461 int QueryExpression::RangeParamCheck() const
462 {
463 if (queryInfo_.size() != 1) { // the query filter must have 1 filter and only the Range query.
464 return -E_INVALID_ARGS;
465 }
466 for (const auto &queryObjNode : queryInfo_) {
467 if (queryObjNode.operFlag != QueryObjType::KEY_RANGE) {
468 return -E_INVALID_ARGS;
469 }
470 }
471 if (this->beginKey_.size() > DBConstant::MAX_KEY_SIZE ||
472 this->endKey_.size() > DBConstant::MAX_KEY_SIZE) {
473 return -E_INVALID_ARGS;
474 }
475 return E_OK;
476 }
477 } // namespace DistributedDB
478