• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SetAssetsOnlyValidStatusIfNeed(int status)223 void QueryExpression::SetAssetsOnlyValidStatusIfNeed(int status)
224 {
225     if (validStatusForAssetsOnly_ != E_OK && validStatusForAssetsOnly_ == -E_INVALID_ARGS) {
226         return;
227     }
228     validStatusForAssetsOnly_ = status;
229 }
230 
QueryAssetsOnly(const AssetsMap & assets)231 void QueryExpression::QueryAssetsOnly(const AssetsMap &assets)
232 {
233     isAssetsOnly_ = true;
234     if (useFromTable_) {
235         expressions_[fromTable_].QueryAssetsOnly(assets);
236         SetAssetsOnlyValidStatusIfNeed(expressions_[fromTable_].GetExpressionStatusForAssetsOnly());
237         return;
238     }
239     if (queryInfo_.empty()) {
240         LOGE("[QueryExpression] the QueryAssetsOnly option must be connected with And.");
241         SetAssetsOnlyValidStatusIfNeed(-E_INVALID_ARGS);
242         return;
243     } else if (queryInfo_.back().operFlag != QueryObjType::AND) {
244         LOGE("[QueryExpression] the QueryAssetsOnly option must be connected with And.");
245         SetAssetsOnlyValidStatusIfNeed(-E_INVALID_ARGS);
246         return;
247     } else {
248         queryInfo_.pop_back();
249     }
250     if (assetsGroupMap_.find(groupNum_) != assetsGroupMap_.end()) {
251         LOGE("[QueryExpression]assets only already set!");
252         SetAssetsOnlyValidStatusIfNeed(-E_NOT_SUPPORT);
253         return;
254     }
255     if (assets.empty()) {
256         LOGE("[QueryExpression]assets map can not be empty!");
257         SetAssetsOnlyValidStatusIfNeed(-E_NOT_SUPPORT);
258         return;
259     }
260     for (const auto &item : assets) {
261         if (item.second.empty() && item.first.empty()) {
262             LOGE("[QueryExpression]assets filed or asset name can not be empty!");
263             SetAssetsOnlyValidStatusIfNeed(-E_NOT_SUPPORT);
264             return;
265         }
266     }
267     assetsGroupMap_[groupNum_] = assets;
268     for (uint32_t i = 0; i <= groupNum_; i++) {
269         if (assetsGroupMap_.find(i) == assetsGroupMap_.end()) {
270             LOGE("[QueryExpression]asset group " PRIu32 " not found, may be AssetsOnly interface use in wrong way.", i);
271             SetAssetsOnlyValidStatusIfNeed(-E_NOT_SUPPORT);
272             return;
273         }
274     }
275 }
276 
QueryBySuggestIndex(const std::string & indexName)277 void QueryExpression::QueryBySuggestIndex(const std::string &indexName)
278 {
279     if (useFromTable_) {
280         expressions_[fromTable_].QueryBySuggestIndex(indexName);
281         validStatus_ = -E_NOT_SUPPORT;
282         return;
283     }
284     SetNotSupportIfFromTables();
285     queryInfo_.emplace_back(QueryObjNode{QueryObjType::SUGGEST_INDEX, indexName,
286         QueryValueType::VALUE_TYPE_STRING, std::vector<FieldValue>()});
287     suggestIndex_ = indexName;
288 }
289 
InKeys(const std::set<Key> & keys)290 void QueryExpression::InKeys(const std::set<Key> &keys)
291 {
292     if (useFromTable_) {
293         expressions_[fromTable_].InKeys(keys);
294         validStatus_ = -E_NOT_SUPPORT;
295         return;
296     }
297     SetNotSupportIfFromTables();
298     queryInfo_.emplace_front(QueryObjNode{QueryObjType::IN_KEYS, std::string(), QueryValueType::VALUE_TYPE_NULL,
299         std::vector<FieldValue>()});
300     keys_ = keys;
301 }
302 
GetQueryExpression()303 const std::list<QueryObjNode> &QueryExpression::GetQueryExpression()
304 {
305     if (!GetErrFlag()) {
306         queryInfo_.clear();
307         queryInfo_.emplace_back(QueryObjNode{QueryObjType::OPER_ILLEGAL});
308         LOGE("Query operate illegal!");
309     }
310     return queryInfo_;
311 }
312 
GetBeginKey() const313 std::vector<uint8_t> QueryExpression::GetBeginKey() const
314 {
315     return beginKey_;
316 }
317 
GetEndKey() const318 std::vector<uint8_t> QueryExpression::GetEndKey() const
319 {
320     return endKey_;
321 }
322 
GetPreFixKey() const323 std::vector<uint8_t> QueryExpression::GetPreFixKey() const
324 {
325     return prefixKey_;
326 }
327 
SetTableName(const std::string & tableName)328 void QueryExpression::SetTableName(const std::string &tableName)
329 {
330     tableName_ = tableName;
331     isTableNameSpecified_ = true;
332 }
333 
GetTableName()334 const std::string &QueryExpression::GetTableName()
335 {
336     return tableName_;
337 }
338 
IsTableNameSpecified() const339 bool QueryExpression::IsTableNameSpecified() const
340 {
341     return isTableNameSpecified_;
342 }
343 
GetSuggestIndex() const344 std::string QueryExpression::GetSuggestIndex() const
345 {
346     return suggestIndex_;
347 }
348 
GetKeys() const349 const std::set<Key> &QueryExpression::GetKeys() const
350 {
351     return keys_;
352 }
353 
BeginGroup()354 void QueryExpression::BeginGroup()
355 {
356     if (useFromTable_) {
357         expressions_[fromTable_].BeginGroup();
358         return;
359     }
360     if (isAssetsOnly_) {
361         auto iter = queryInfo_.rbegin();
362         if (iter != queryInfo_.rend() && (*iter).operFlag != QueryObjType::OR) {
363             validStatusForAssetsOnly_ = -E_NOT_SUPPORT;
364         }
365     }
366     SetNotSupportIfFromTables();
367     queryInfo_.emplace_back(QueryObjNode{QueryObjType::BEGIN_GROUP, std::string(),
368         QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>()});
369 }
370 
EndGroup()371 void QueryExpression::EndGroup()
372 {
373     if (useFromTable_) {
374         expressions_[fromTable_].EndGroup();
375         return;
376     }
377     SetNotSupportIfFromTables();
378     groupNum_++;
379     queryInfo_.emplace_back(QueryObjNode{QueryObjType::END_GROUP, std::string(),
380         QueryValueType::VALUE_TYPE_NULL, std::vector<FieldValue>()});
381 }
382 
Reset()383 void QueryExpression::Reset()
384 {
385     errFlag_ = true;
386     queryInfo_.clear();
387     prefixKey_.clear();
388     prefixKey_.shrink_to_fit();
389     suggestIndex_.clear();
390     keys_.clear();
391 }
392 
SetErrFlag(bool flag)393 void QueryExpression::SetErrFlag(bool flag)
394 {
395     errFlag_ = flag;
396 }
397 
GetErrFlag()398 bool QueryExpression::GetErrFlag()
399 {
400     return errFlag_;
401 }
402 
GetSortType() const403 int QueryExpression::GetSortType() const
404 {
405     return sortType_;
406 }
407 
SetSortType(bool isAsc)408 void QueryExpression::SetSortType(bool isAsc)
409 {
410     if (useFromTable_) {
411         expressions_[fromTable_].SetSortType(isAsc);
412         validStatus_ = -E_NOT_SUPPORT;
413         return;
414     }
415     SetNotSupportIfFromTables();
416     WriteTimeSort sortType = isAsc ? WriteTimeSort::TIMESTAMP_ASC : WriteTimeSort::TIMESTAMP_DESC;
417     sortType_ = static_cast<int>(sortType);
418 }
419 
GetTables()420 std::vector<std::string> QueryExpression::GetTables()
421 {
422     return tables_;
423 }
424 
SetTables(const std::vector<std::string> & tableNames)425 void QueryExpression::SetTables(const std::vector<std::string> &tableNames)
426 {
427     // filter same table
428     std::vector<std::string> syncTable;
429     std::set<std::string> addTable;
430     for (const auto &table: tableNames) {
431         if (addTable.find(table) == addTable.end()) {
432             addTable.insert(table);
433             syncTable.push_back(table);
434         }
435     }
436     tables_ = syncTable;
437     isUseFromTables_ = true;
438     if (useFromTable_) {
439         validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_NOT_SUPPORT;
440     }
441     SetNotSupportIfCondition();
442 }
443 
From(const std::string & tableName)444 void QueryExpression::From(const std::string &tableName)
445 {
446     useFromTable_ = true;
447     fromTable_ = tableName;
448     for (const auto &item: tableSequence_) {
449         if (item == tableName) {
450             return;
451         }
452     }
453     tableSequence_.push_back(fromTable_);
454     expressions_[fromTable_].SetTableName(fromTable_);
455     if (tableName.empty()) {
456         validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_INVALID_ARGS;
457     } else if (!tables_.empty()) {
458         validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_NOT_SUPPORT;
459     }
460     SetNotSupportIfFromTables();
461     SetNotSupportIfCondition();
462 }
463 
GetExpressionStatus() const464 int QueryExpression::GetExpressionStatus() const
465 {
466     return validStatus_;
467 }
468 
GetExpressionStatusForAssetsOnly() const469 int QueryExpression::GetExpressionStatusForAssetsOnly() const
470 {
471     return validStatusForAssetsOnly_;
472 }
473 
GetQueryExpressions() const474 std::vector<QueryExpression> QueryExpression::GetQueryExpressions() const
475 {
476     if (!useFromTable_) {
477         return {};
478     }
479     std::vector<QueryExpression> res;
480     for (const auto &item : tableSequence_) {
481         res.push_back(expressions_.at(item));
482     }
483     return res;
484 }
485 
SetNotSupportIfFromTables()486 void QueryExpression::SetNotSupportIfFromTables()
487 {
488     if (validStatus_ != E_OK) {
489         return;
490     }
491     if (!tables_.empty()) {
492         validStatus_ = -E_NOT_SUPPORT;
493     }
494 }
495 
SetNotSupportIfCondition()496 void QueryExpression::SetNotSupportIfCondition()
497 {
498     if (validStatus_ != E_OK) {
499         return;
500     }
501     if (!queryInfo_.empty()) {
502         validStatus_ = -E_NOT_SUPPORT;
503     }
504 }
505 
SetNotSupportIfNeed(QueryObjType type)506 void QueryExpression::SetNotSupportIfNeed(QueryObjType type)
507 {
508     if (validStatus_ != E_OK) {
509         return;
510     }
511     if (type != QueryObjType::IN && type != QueryObjType::EQUALTO && type != QueryObjType::AND &&
512         type != QueryObjType::OR) {
513         validStatus_ = -E_NOT_SUPPORT;
514     }
515     if (validStatus_ != E_OK) {
516         return;
517     }
518     for (const auto &item: queryInfo_) {
519         if (((item.operFlag == QueryObjType::EQUALTO) && (type == QueryObjType::IN)) ||
520             ((item.operFlag == QueryObjType::IN) && (type == QueryObjType::EQUALTO))) {
521             validStatus_ = -E_NOT_SUPPORT;
522             LOGW("[Query] Not support use in and equal to at same time when use from table");
523             break;
524         }
525     }
526 }
527 
RangeParamCheck() const528 int QueryExpression::RangeParamCheck() const
529 {
530     if (queryInfo_.size() != 1) { // the query filter must have 1 filter and only the Range query.
531         return -E_INVALID_ARGS;
532     }
533     for (const auto &queryObjNode : queryInfo_) {
534         if (queryObjNode.operFlag != QueryObjType::KEY_RANGE) {
535             return -E_INVALID_ARGS;
536         }
537     }
538     if (this->beginKey_.size() > DBConstant::MAX_KEY_SIZE ||
539         this->endKey_.size() > DBConstant::MAX_KEY_SIZE) {
540         return -E_INVALID_ARGS;
541     }
542     return E_OK;
543 }
544 
IsAssetsOnly() const545 bool QueryExpression::IsAssetsOnly() const
546 {
547     return isAssetsOnly_;
548 }
549 
GetAssetsOnlyGroupMap() const550 AssetsGroupMap QueryExpression::GetAssetsOnlyGroupMap() const
551 {
552     return assetsGroupMap_;
553 }
554 
GetGroupNum() const555 uint32_t QueryExpression::GetGroupNum() const
556 {
557     return groupNum_;
558 }
559 
IsUseFromTables() const560 bool QueryExpression::IsUseFromTables() const
561 {
562     return isUseFromTables_;
563 }
564 } // namespace DistributedDB
565