• 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 "sqlite_query_helper.h"
16 
17 #include <iomanip>
18 
19 #include "db_common.h"
20 #include "db_constant.h"
21 #include "db_errno.h"
22 #include "log_print.h"
23 #include "macro_utils.h"
24 #include "sqlite_utils.h"
25 #include "cloud/cloud_storage_utils.h"
26 
27 namespace DistributedDB {
28 using namespace TriggerMode;
29 namespace {
30 const std::string PRE_QUERY_KV_SQL = "SELECT key, value FROM sync_data ";
31 const std::string PRE_QUERY_ITEM_SQL = "SELECT * FROM ";
32 const std::string PRE_QUERY_ROWID_SQL = "SELECT rowid FROM sync_data ";
33 const std::string PRE_GET_COUNT_SQL = "SELECT count(*) FROM sync_data ";
34 const std::string FILTER_NATIVE_DATA_SQL = "WHERE (flag&0x01=0) ";
35 const std::string FILTER_REMOTE_QUERY = "WHERE (flag&0x03=0x02)";
36 const std::string USING_INDEX = "INDEXED BY ";
37 const int MAX_SQL_LEN = 1024 * 1024; // 1M bytes
38 const int SINGLE_FIELD_VALUE_SIZE = 1;
39 const int MAX_CONDITIONS_SIZE = 128;
40 const int MAX_SQLITE_BIND_SIZE = 50000;
41 const uint32_t SYMBOL_TYPE_MASK = 0xff00;
42 
43 const std::map<QueryObjType, std::string> RELATIONAL_SYMBOL_TO_SQL {
44     {QueryObjType::EQUALTO, "= "},
45     {QueryObjType::NOT_EQUALTO, "!= "},
46     {QueryObjType::GREATER_THAN, "> "},
47     {QueryObjType::LESS_THAN, "< "},
48     {QueryObjType::GREATER_THAN_OR_EQUALTO, ">= "},
49     {QueryObjType::LESS_THAN_OR_EQUALTO, "<= "},
50     {QueryObjType::LIKE, " LIKE "},
51     {QueryObjType::NOT_LIKE, " NOT LIKE "},
52     {QueryObjType::IS_NULL, " IS NULL "},
53     {QueryObjType::IS_NOT_NULL, " IS NOT NULL "},
54     {QueryObjType::IN, " IN ("},
55     {QueryObjType::NOT_IN, " NOT IN ("},
56 };
57 
58 const std::map<QueryObjType, std::string> LOGIC_SYMBOL_TO_SQL {
59     {QueryObjType::AND, " AND "},
60     {QueryObjType::OR, " OR "},
61     {QueryObjType::BEGIN_GROUP, "("},
62     {QueryObjType::END_GROUP, ")"},
63 };
64 
FieldValue2String(const FieldValue & val,QueryValueType type)65 std::string FieldValue2String(const FieldValue &val, QueryValueType type)
66 {
67     std::stringstream ss;
68     switch (type) {
69         case QueryValueType::VALUE_TYPE_NULL:
70             return "NULL";
71         case QueryValueType::VALUE_TYPE_BOOL:
72             return val.boolValue ? "1" : "0";
73         case QueryValueType::VALUE_TYPE_INTEGER:
74             return std::to_string(val.integerValue);
75         case QueryValueType::VALUE_TYPE_LONG:
76             return std::to_string(val.longValue);
77         case QueryValueType::VALUE_TYPE_DOUBLE:
78             ss << std::setprecision(DBConstant::DOUBLE_PRECISION) << val.doubleValue;
79             return ss.str();
80         case QueryValueType::VALUE_TYPE_STRING:
81             return "'" + val.stringValue + "'";
82         case QueryValueType::VALUE_TYPE_INVALID:
83         default:
84             return "";
85     }
86 }
87 
GetSelectAndFromClauseForRDB(const std::string & tableName,const std::vector<std::string> & fieldNames)88 std::string GetSelectAndFromClauseForRDB(const std::string &tableName, const std::vector<std::string> &fieldNames)
89 {
90     std::string sql = "SELECT b.data_key,"
91         "b.device,"
92         "b.ori_device,"
93         "b.timestamp as " + DBConstant::TIMESTAMP_ALIAS + ","
94         "b.wtimestamp,"
95         "b.flag,"
96         "b.hash_key,";
97     if (fieldNames.empty()) {  // For query check. If column count changed, can be discovered.
98         sql += "a.*";
99     } else {
100         for (const auto &fieldName : fieldNames) {  // For query data.
101             sql += "a.'" + fieldName + "',";
102         }
103         sql.pop_back();
104     }
105     sql += " FROM '" + tableName + "' AS a INNER JOIN " + DBConstant::RELATIONAL_PREFIX + tableName + "_log AS b "
106         "ON a." + std::string(DBConstant::SQLITE_INNER_ROWID) + "=b.data_key ";
107     return sql;
108 }
109 
GetTimeRangeClauseForRDB()110 std::string GetTimeRangeClauseForRDB()
111 {
112     return " AND (" + DBConstant::TIMESTAMP_ALIAS + ">=? AND " + DBConstant::TIMESTAMP_ALIAS + "<?) ";
113 }
114 
GetOuterQueryClauseForRDB(const std::string & subQueryClause)115 std::string GetOuterQueryClauseForRDB(const std::string &subQueryClause)
116 {
117     return "SELECT * "
118         "FROM ( " + subQueryClause + " ) "
119         "WHERE (" + DBConstant::TIMESTAMP_ALIAS + ">=? AND " + DBConstant::TIMESTAMP_ALIAS + "<?) "
120         "ORDER BY " + DBConstant::TIMESTAMP_ALIAS + ";";
121 }
122 
GetFlagClauseForRDB()123 std::string GetFlagClauseForRDB()
124 {
125     return "WHERE (b.flag&0x03=0x02)";
126 }
127 
GetMissQueryFlagClauseForRDB()128 std::string GetMissQueryFlagClauseForRDB()
129 {
130     return "WHERE (b.flag&0x23=0x22)";
131 }
132 }
133 
SqliteQueryHelper(const QueryObjInfo & info)134 SqliteQueryHelper::SqliteQueryHelper(const QueryObjInfo &info)
135     : schema_(info.schema_),
136       queryObjNodes_(info.queryObjNodes_),
137       prefixKey_(info.prefixKey_),
138       suggestIndex_(info.suggestIndex_),
139       tableName_(info.tableName_),
140       keys_(info.keys_),
141       orderByCounts_(info.orderByCounts_),
142       isValid_(info.isValid_),
143       transformed_(false),
144       hasOrderBy_(info.hasOrderBy_),
145       hasLimit_(info.hasLimit_),
146       isOrderByAppeared_(false),
147       hasPrefixKey_(info.hasPrefixKey_),
148       isNeedOrderbyKey_(false),
149       isRelationalQuery_(info.isRelationalQuery_),
150       sortType_(info.sortType_)
151 {}
152 
GetSymbolType(const QueryObjType & queryObjType)153 SymbolType SqliteQueryHelper::GetSymbolType(const QueryObjType &queryObjType)
154 {
155     return static_cast<SymbolType>(static_cast<uint32_t>(queryObjType) & SYMBOL_TYPE_MASK);
156 }
157 
FilterSymbolToAddBracketLink(std::string & querySql,bool isNeedLink) const158 bool SqliteQueryHelper::FilterSymbolToAddBracketLink(std::string &querySql, bool isNeedLink) const
159 {
160     bool isNeedEndBracket = false;
161     for (const auto &iter : queryObjNodes_) {
162         SymbolType symbolType = GetSymbolType(iter.operFlag);
163         if (symbolType == SymbolType::COMPARE_SYMBOL || symbolType == SymbolType::RELATIONAL_SYMBOL ||
164             symbolType == SymbolType::RANGE_SYMBOL) {
165             querySql += isNeedLink ? " AND (" : " (";
166             isNeedEndBracket = true;
167             break;
168         } else if (symbolType == SymbolType::LOGIC_SYMBOL || symbolType == SymbolType::PREFIXKEY_SYMBOL ||
169             symbolType == SymbolType::IN_KEYS_SYMBOL) {
170             continue;
171         } else {
172             break;
173         }
174     }
175     return isNeedEndBracket;
176 }
177 
178 
ParseQueryObjNodeToSQL(bool isQueryForSync)179 int SqliteQueryHelper::ParseQueryObjNodeToSQL(bool isQueryForSync)
180 {
181     if (queryObjNodes_.empty()) {
182         if (!isQueryForSync) {
183             querySql_ += ";";
184         }
185         return E_OK;
186     }
187 
188     bool isNeedEndBracket = FilterSymbolToAddBracketLink(querySql_);
189 
190     int errCode = E_OK;
191     for (const QueryObjNode &objNode : queryObjNodes_) {
192         SymbolType symbolType = GetSymbolType(objNode.operFlag);
193         if (symbolType == SymbolType::SPECIAL_SYMBOL && isNeedEndBracket) {
194             querySql_ += ") ";
195             isNeedEndBracket = false;
196         }
197         errCode = ParseQueryExpression(objNode, querySql_);
198         if (errCode != E_OK) {
199             querySql_.clear();
200             return errCode;
201         }
202     }
203 
204     if (isNeedEndBracket) {
205         querySql_ += ") ";
206     }
207 
208     return errCode;
209 }
210 
ToQuerySql()211 int SqliteQueryHelper::ToQuerySql()
212 {
213     int errCode = ParseQueryObjNodeToSQL(false);
214     if (errCode != E_OK) {
215         return errCode;
216     }
217 
218     // Limit needs to be placed after orderBy and processed separately in the limit branch
219     if (hasPrefixKey_ && !hasOrderBy_ && !hasLimit_ && isNeedOrderbyKey_) {
220         LOGD("Need add order by key at last when has prefixKey no need order by value and limit!");
221         querySql_ += "ORDER BY key ASC";
222     }
223     querySql_ += ";";
224     return errCode;
225 }
226 
ToQuerySyncSql(bool hasSubQuery,bool useTimestampAlias)227 int SqliteQueryHelper::ToQuerySyncSql(bool hasSubQuery, bool useTimestampAlias)
228 {
229     int errCode = ParseQueryObjNodeToSQL(true);
230     if (errCode != E_OK) {
231         return errCode;
232     }
233 
234     // Order by time when no order by and no limit and no need order by key.
235     if (!hasOrderBy_ && !hasLimit_ && !isNeedOrderbyKey_) {
236         querySql_ += (useTimestampAlias ?
237             ("ORDER BY " + DBConstant::TIMESTAMP_ALIAS + " ASC") :
238             "ORDER BY timestamp ASC");
239     }
240 
241     if (!hasSubQuery) {
242         querySql_ += ";";
243     }
244     return errCode;
245 }
246 
ToGetCountSql()247 int SqliteQueryHelper::ToGetCountSql()
248 {
249     countSql_.clear();
250     if (queryObjNodes_.empty()) {
251         countSql_ += ";";
252         return E_OK;
253     }
254     bool isNeedEndBracket = FilterSymbolToAddBracketLink(countSql_);
255 
256     int errCode = E_OK;
257     for (const QueryObjNode &objNode : queryObjNodes_) {
258         SymbolType symbolType = GetSymbolType(objNode.operFlag);
259         if (symbolType == SymbolType::SPECIAL_SYMBOL && isNeedEndBracket) {
260             countSql_ += ") ";
261             isNeedEndBracket = false;
262         }
263 
264         if (objNode.operFlag == QueryObjType::LIMIT) {
265             hasLimit_ = true;
266             continue;
267         }
268         if (objNode.operFlag == QueryObjType::ORDERBY) {
269             hasOrderBy_ = true;
270             continue;
271         }
272         errCode = ParseQueryExpression(objNode, countSql_);
273         if (errCode != E_OK) {
274             countSql_.clear();
275             return errCode;
276         }
277     }
278 
279     if (isNeedEndBracket) {
280         countSql_ += ") ";
281     }
282 
283     // Limit needs to be placed after orderBy and processed separately in the limit branch
284     if (hasPrefixKey_ && !hasOrderBy_ && !hasLimit_ && isNeedOrderbyKey_) {
285         LOGD("Need add order by key at last when has prefixKey no need order by value and limit!");
286         countSql_ += "ORDER BY key ASC";
287     }
288     countSql_ += ";";
289     return errCode;
290 }
291 
GetQuerySql(std::string & sql,bool onlyRowid)292 int SqliteQueryHelper::GetQuerySql(std::string &sql, bool onlyRowid)
293 {
294     if (!isValid_) {
295         return -E_INVALID_QUERY_FORMAT;
296     }
297 
298     const std::string &querySqlForUse = (onlyRowid ? PRE_QUERY_ROWID_SQL : PRE_QUERY_KV_SQL);
299     sql = AssembleSqlForSuggestIndex(querySqlForUse, FILTER_NATIVE_DATA_SQL);
300     sql = !hasPrefixKey_ ? sql : (sql + " AND (key>=? AND key<=?) ");
301     sql = keys_.empty() ? sql : (sql + " AND " + MapKeysInToSql(keys_.size()));
302     if (sortType_ != SortType::NONE) {
303         sql += (sortType_ == SortType::TIMESTAMP_ASC) ? "ORDER BY timestamp asc " : "ORDER BY timestamp desc ";
304     }
305     if (transformed_) {
306         LOGD("This query object has been parsed.");
307         sql += querySql_;
308         return E_OK;
309     }
310     int errCode = ToQuerySql();
311     if (errCode != E_OK) {
312         LOGE("Transfer to query sql failed! errCode[%d]", errCode);
313         return errCode;
314     }
315     transformed_ = true;
316     sql += querySql_;
317     return errCode;
318 }
319 
GetSyncDataCheckSql(std::string & sql)320 int SqliteQueryHelper::GetSyncDataCheckSql(std::string &sql)
321 {
322     int errCode = E_OK;
323     if (!isValid_) {
324         return -E_INVALID_QUERY_FORMAT;
325     }
326     sql = PRE_QUERY_ITEM_SQL + tableName_ + " WHERE hash_key=? AND (flag&0x01=0) ";
327     sql += hasPrefixKey_ ? " AND (key>=? AND key<=?) " : "";
328     sql = keys_.empty() ? sql : (sql + " AND " + MapKeysInToSql(keys_.size()));
329     if (!transformed_) {
330         errCode = ToQuerySql();
331         if (errCode != E_OK) {
332             LOGE("Transfer query to sync data check sql failed! errCode[%d]", errCode);
333             return errCode;
334         }
335         transformed_ = true;
336     }
337     sql += querySql_;
338     return errCode;
339 }
340 
BindSyncDataCheckStmt(sqlite3_stmt * statement,const Key & hashKey) const341 int SqliteQueryHelper::BindSyncDataCheckStmt(sqlite3_stmt *statement, const Key &hashKey) const
342 {
343     if (statement == nullptr) {
344         return -E_INVALID_ARGS;
345     }
346     int index = 1; // bind statement start index 1
347     int errCode = SQLiteUtils::BindBlobToStatement(statement, index++, hashKey, false);
348     if (errCode != E_OK) {
349         LOGE("Get sync data check statement failed when bind hash key, errCode = %d", errCode);
350         return errCode;
351     }
352     if (hasPrefixKey_) {
353         // bind the prefix key for the first and second args.
354         errCode = SQLiteUtils::BindPrefixKey(statement, index, prefixKey_);
355         if (errCode != E_OK) {
356             LOGE("Get sync data check statement failed when bind prefix key, errCode = %d", errCode);
357             return errCode;
358         }
359         index += 2; // prefixKey takes 2 position
360     }
361 
362     errCode = BindKeysToStmt(keys_, statement, index);
363     if (errCode != E_OK) {
364         SQLiteUtils::ResetStatement(statement, true, errCode);
365         return errCode;
366     }
367 
368     for (const QueryObjNode &objNode : queryObjNodes_) {
369         errCode = BindFieldValue(statement, objNode, index);
370         if (errCode != E_OK) {
371             LOGE("Get sync data check statement failed when bind field value, errCode = %d", errCode);
372             return errCode;
373         }
374     }
375     return errCode;
376 }
377 
GetCountQuerySql(std::string & sql)378 int SqliteQueryHelper::GetCountQuerySql(std::string &sql)
379 {
380     if (!isValid_) {
381         return -E_INVALID_QUERY_FORMAT;
382     }
383 
384     int errCode = ToGetCountSql();
385     if (errCode != E_OK) {
386         return errCode;
387     }
388     sql = AssembleSqlForSuggestIndex(PRE_GET_COUNT_SQL, FILTER_NATIVE_DATA_SQL);
389     sql = !hasPrefixKey_ ? sql : (sql + " AND (key>=? AND key<=?) ");
390     sql = keys_.empty() ? sql : (sql + " AND " + MapKeysInToSql(keys_.size()));
391     sql += countSql_;
392     return E_OK;
393 }
394 
GetQuerySqlStatement(sqlite3 * dbHandle,const std::string & sql,sqlite3_stmt * & statement)395 int SqliteQueryHelper::GetQuerySqlStatement(sqlite3 *dbHandle, const std::string &sql, sqlite3_stmt *&statement)
396 {
397     int errCode = SQLiteUtils::GetStatement(dbHandle, sql, statement);
398     if (errCode != E_OK) {
399         LOGE("[Query] Get statement fail!");
400         return -E_INVALID_QUERY_FORMAT;
401     }
402     int index = 1;
403     if (hasPrefixKey_) {
404         // bind the prefix key for the first and second args.
405         errCode = SQLiteUtils::BindPrefixKey(statement, 1, prefixKey_);
406         if (errCode != E_OK) {
407             SQLiteUtils::ResetStatement(statement, true, errCode);
408             LOGE("[Query] Get statement when bind prefix key, errCode = %d", errCode);
409             return errCode;
410         }
411         index = 3; // begin from 3rd args
412     }
413 
414     errCode = BindKeysToStmt(keys_, statement, index);
415     if (errCode != E_OK) {
416         SQLiteUtils::ResetStatement(statement, true, errCode);
417         return errCode;
418     }
419 
420     for (const QueryObjNode &objNode : queryObjNodes_) {
421         errCode = BindFieldValue(statement, objNode, index);
422         if (errCode != E_OK) {
423             SQLiteUtils::ResetStatement(statement, true, errCode);
424             LOGE("[Query] Get statement fail when bind field value, errCode = %d", errCode);
425             return errCode;
426         }
427     }
428     return errCode;
429 }
430 
GetQuerySqlStatement(sqlite3 * dbHandle,bool onlyRowid,sqlite3_stmt * & statement)431 int SqliteQueryHelper::GetQuerySqlStatement(sqlite3 *dbHandle, bool onlyRowid, sqlite3_stmt *&statement)
432 {
433     std::string sql;
434     int errCode = GetQuerySql(sql, onlyRowid);
435     if (errCode != E_OK) {
436         return errCode;
437     }
438 
439     errCode = SQLiteUtils::GetStatement(dbHandle, sql, statement);
440     if (errCode != E_OK) {
441         LOGE("[Query] Get statement fail!");
442         return -E_INVALID_QUERY_FORMAT;
443     }
444     int index = 1;
445     if (hasPrefixKey_) {
446         // bind the prefix key for the first and second args.
447         errCode = SQLiteUtils::BindPrefixKey(statement, 1, prefixKey_);
448         if (errCode != E_OK) {
449             LOGE("[Query] Get statement when bind prefix key, errCode = %d", errCode);
450             return errCode;
451         }
452         index = 3; // begin from 3rd args
453     }
454 
455     errCode = BindKeysToStmt(keys_, statement, index);
456     if (errCode != E_OK) {
457         return errCode;
458     }
459 
460     for (const QueryObjNode &objNode : queryObjNodes_) {
461         errCode = BindFieldValue(statement, objNode, index);
462         if (errCode != E_OK) {
463             LOGE("[Query] Get statement fail when bind field value, errCode = %d", errCode);
464             return errCode;
465         }
466     }
467     return errCode;
468 }
469 
GetCountSqlStatement(sqlite3 * dbHandle,sqlite3_stmt * & countStmt)470 int SqliteQueryHelper::GetCountSqlStatement(sqlite3 *dbHandle, sqlite3_stmt *&countStmt)
471 {
472     std::string countSql;
473     int errCode = GetCountQuerySql(countSql);
474     if (errCode != E_OK) {
475         return errCode;
476     }
477 
478     // bind statement for count
479     errCode = SQLiteUtils::GetStatement(dbHandle, countSql, countStmt);
480     if (errCode != E_OK) {
481         LOGE("Get count statement error:%d", errCode);
482         return -E_INVALID_QUERY_FORMAT;
483     }
484     int index = 1;
485     if (hasPrefixKey_) {
486         // bind the prefix key for the first and second args.
487         errCode = SQLiteUtils::BindPrefixKey(countStmt, 1, prefixKey_);
488         if (errCode != E_OK) {
489             LOGE("[Query] Get count statement fail when bind prefix key, errCode = %d", errCode);
490             return errCode;
491         }
492         index = 3; // begin from 3rd args
493     }
494 
495     errCode = BindKeysToStmt(keys_, countStmt, index);
496     if (errCode != E_OK) {
497         return errCode;
498     }
499 
500     for (const QueryObjNode &objNode : queryObjNodes_) {
501         if (GetSymbolType(objNode.operFlag) == SymbolType::SPECIAL_SYMBOL) {
502             continue;
503         }
504         errCode = BindFieldValue(countStmt, objNode, index);
505         if (errCode != E_OK) {
506             LOGE("[Query] Get count statement fail when bind field value, errCode = %d", errCode);
507             return errCode;
508         }
509     }
510     return errCode;
511 }
512 
GetSyncDataQuerySql(std::string & sql,bool hasSubQuery)513 int SqliteQueryHelper::GetSyncDataQuerySql(std::string &sql, bool hasSubQuery)
514 {
515     if (!isValid_) {
516         return -E_INVALID_QUERY_FORMAT;
517     }
518 
519     if (hasLimit_) {
520         hasSubQuery = true; // Need sub query.
521     } else {
522         isNeedOrderbyKey_ = false; // Need order by timestamp.
523     }
524 
525     sql = AssembleSqlForSuggestIndex(PRE_QUERY_ITEM_SQL + tableName_ + " ", FILTER_REMOTE_QUERY);
526     sql = !hasPrefixKey_ ? sql : (sql + " AND (key>=? AND key<=?) ");
527     sql = keys_.empty() ? sql : (sql + " AND " + MapKeysInToSql(keys_.size()));
528     sql = hasSubQuery ? sql : (sql + " AND (timestamp>=? AND timestamp<?) ");
529 
530     querySql_.clear(); // clear local query sql format
531     int errCode = ToQuerySyncSql(hasSubQuery);
532     if (errCode != E_OK) {
533         LOGE("To query sql fail! errCode[%d]", errCode);
534         return errCode;
535     }
536     sql += querySql_;
537     if (hasSubQuery) {
538         // The last timestamp in one query will be stored in continue token and used for next query.
539         // Therefore all query data must be ordered by timestamp.
540         // When there is limit in SQL, data should be ordered by key in sub query, and timestamp is ordered by outside.
541         sql = "SELECT * FROM ( " + sql + " ) WHERE (timestamp >= ? AND timestamp < ?) ORDER BY timestamp;";
542     }
543     return errCode;
544 }
545 
BindTimeRange(sqlite3_stmt * & statement,int & index,uint64_t beginTime,uint64_t endTime) const546 int SqliteQueryHelper::BindTimeRange(sqlite3_stmt *&statement, int &index, uint64_t beginTime, uint64_t endTime) const
547 {
548     int errCode = SQLiteUtils::BindInt64ToStatement(statement, index++, beginTime);
549     if (errCode != E_OK) {
550         SQLiteUtils::ResetStatement(statement, true, errCode);
551         return errCode;
552     }
553 
554     errCode = SQLiteUtils::BindInt64ToStatement(statement, index++, endTime);
555     if (errCode != E_OK) {
556         SQLiteUtils::ResetStatement(statement, true, errCode);
557     }
558     return errCode;
559 }
560 
BindObjNodes(sqlite3_stmt * & statement,int & index) const561 int SqliteQueryHelper::BindObjNodes(sqlite3_stmt *&statement, int &index) const
562 {
563     int errCode = E_OK;
564     for (const QueryObjNode &objNode : queryObjNodes_) {
565         errCode = BindFieldValue(statement, objNode, index);
566         if (errCode != E_OK) {
567             SQLiteUtils::ResetStatement(statement, true, errCode);
568             LOGE("[Query] Get statement fail when bind field value, errCode = %d", errCode);
569             break;
570         }
571     }
572     return errCode;
573 }
574 
GetQuerySyncStatement(sqlite3 * dbHandle,uint64_t beginTime,uint64_t endTime,sqlite3_stmt * & statement)575 int SqliteQueryHelper::GetQuerySyncStatement(sqlite3 *dbHandle, uint64_t beginTime, uint64_t endTime,
576     sqlite3_stmt *&statement)
577 {
578     bool hasSubQuery = false;
579     if (hasLimit_) {
580         hasSubQuery = true; // Need sub query.
581     } else {
582         isNeedOrderbyKey_ = false; // Need order by timestamp.
583     }
584     std::string sql;
585     int errCode = GetSyncDataQuerySql(sql, hasSubQuery);
586     if (errCode != E_OK) {
587         LOGE("[Query] Get SQL fail!");
588         return -E_INVALID_QUERY_FORMAT;
589     }
590 
591     errCode = SQLiteUtils::GetStatement(dbHandle, sql, statement);
592     if (errCode != E_OK) {
593         LOGE("[Query] Get statement fail!");
594         return -E_INVALID_QUERY_FORMAT;
595     }
596 
597     int index = 1; // begin with 1.
598     if (hasPrefixKey_) {
599         // bind the prefix key for the first and second args.
600         errCode = SQLiteUtils::BindPrefixKey(statement, index, prefixKey_);
601         if (errCode != E_OK) {
602             SQLiteUtils::ResetStatement(statement, true, errCode);
603             LOGE("[Query] Get statement when bind prefix key, errCode = %d", errCode);
604             return errCode;
605         }
606         index = 3; // begin with 3 next if prefix key exists.
607     }
608 
609     errCode = BindKeysToStmt(keys_, statement, index);
610     if (errCode != E_OK) {
611         SQLiteUtils::ResetStatement(statement, true, errCode);
612         return errCode;
613     }
614 
615     if (hasSubQuery) {
616         // For sub query SQL, timestamp must be last : (prefix key), (objNodes), timestamp.
617         // SQL: SELECT * FROM ( SELECT * FROM sync_data WHERE (flag&0x03=0x02) LIMIT 10 OFFSET 0 ) WHERE (timestamp>=?
618         //      AND timestamp<?) ORDER BY timestamp;
619         errCode = BindObjNodes(statement, index);
620         if (errCode != E_OK) {
621             return errCode;
622         }
623         errCode = BindTimeRange(statement, index, beginTime, endTime);
624     } else {
625         // For normal SQL(no sub query), timestamp is just behind prefix key : (prefix key), timestamp, (ojbNodes).
626         // SQL: SELECT * FROM sync_data WHERE (timestamp>=? AND timestamp<?) AND (flag&0x03=0x02) ORDER BY timestamp;
627         errCode = BindTimeRange(statement, index, beginTime, endTime);
628         if (errCode != E_OK) {
629             return errCode;
630         }
631         errCode = BindObjNodes(statement, index);
632     }
633     return errCode;
634 }
635 
MapRelationalSymbolToSql(const QueryObjNode & queryNode,bool placeholder) const636 std::string SqliteQueryHelper::MapRelationalSymbolToSql(const QueryObjNode &queryNode, bool placeholder) const
637 {
638     if (RELATIONAL_SYMBOL_TO_SQL.find(queryNode.operFlag) == RELATIONAL_SYMBOL_TO_SQL.end()) {
639         return "";
640     };
641     std::string sql = RELATIONAL_SYMBOL_TO_SQL.at(queryNode.operFlag) + MapValueToSql(queryNode, placeholder);
642     if (GetSymbolType(queryNode.operFlag) == SymbolType::RANGE_SYMBOL) {
643         sql += ")";
644     }
645     return sql;
646 }
647 
MapLogicSymbolToSql(const QueryObjNode & queryNode) const648 std::string SqliteQueryHelper::MapLogicSymbolToSql(const QueryObjNode &queryNode) const
649 {
650     if (LOGIC_SYMBOL_TO_SQL.find(queryNode.operFlag) == LOGIC_SYMBOL_TO_SQL.end()) {
651         return "";
652     }
653     return LOGIC_SYMBOL_TO_SQL.at(queryNode.operFlag);
654 }
655 
MapKeywordSymbolToSql(const QueryObjNode & queryNode)656 std::string SqliteQueryHelper::MapKeywordSymbolToSql(const QueryObjNode &queryNode)
657 {
658     std::string sql;
659     switch (queryNode.operFlag) {
660         case QueryObjType::ORDERBY:
661             if (queryNode.fieldValue.size() == SINGLE_FIELD_VALUE_SIZE) {
662                 if (!isOrderByAppeared_) {
663                     sql += "ORDER BY ";
664                 }
665                 sql += GetFieldShape(queryNode);
666                 sql += queryNode.fieldValue[0].boolValue ? "ASC," : "DESC,";
667                 orderByCounts_--;
668                 if (orderByCounts_ == 0) {
669                     sql.pop_back();
670                 }
671                 isOrderByAppeared_ = true;
672             }
673             return sql;
674         case QueryObjType::LIMIT:
675             if (hasPrefixKey_ && !hasOrderBy_ && isNeedOrderbyKey_) {
676                 sql += "ORDER BY key ASC ";
677             }
678             sql += " LIMIT " + std::to_string(queryNode.fieldValue[0].integerValue);
679             sql += " OFFSET " + std::to_string(queryNode.fieldValue[1].integerValue);
680             return sql;
681         default:
682             return "";
683     }
684 }
685 
MapValueToSql(const QueryObjNode & queryNode,bool placeholder) const686 std::string SqliteQueryHelper::MapValueToSql(const QueryObjNode &queryNode, bool placeholder) const
687 {
688     std::string resultSql;
689     for (size_t i = 0; i < queryNode.fieldValue.size(); i++) {
690         if (i != 0) {
691             resultSql += ", ";
692         }
693         resultSql += placeholder ? "? " : FieldValue2String(queryNode.fieldValue[i], queryNode.type);
694     }
695     return resultSql;
696 }
697 
IsNeedCastWitEmptyValue(const QueryObjNode & queryNode)698 static bool IsNeedCastWitEmptyValue(const QueryObjNode &queryNode)
699 {
700     return (queryNode.operFlag == QueryObjType::IS_NULL || queryNode.operFlag == QueryObjType::IS_NOT_NULL ||
701         queryNode.operFlag == QueryObjType::IN || queryNode.operFlag == QueryObjType::NOT_IN);
702 }
703 
MapCastFuncSql(const QueryObjNode & queryNode,const std::string & accessStr)704 std::string SqliteQueryHelper::MapCastFuncSql(const QueryObjNode &queryNode, const std::string &accessStr)
705 {
706     std::string resultSql;
707     if (queryNode.fieldValue.empty() && !IsNeedCastWitEmptyValue(queryNode)) {
708         return resultSql;
709     }
710     // fieldPath and isQueryable had been checked ok in the previous code, So here parse path and get type won't fail.
711     FieldPath fieldPath;
712     SchemaUtils::ParseAndCheckFieldPath(queryNode.fieldName, fieldPath);
713     FieldType fieldType = FieldType::LEAF_FIELD_INTEGER;
714     schema_.CheckQueryableAndGetFieldType(fieldPath, fieldType);
715     resultSql += SchemaObject::GenerateExtractSQL(schema_.GetSchemaType(), fieldPath, fieldType,
716         schema_.GetSkipSize(), accessStr);
717     isNeedOrderbyKey_ = false; // When index by value, No need order by key!
718     return resultSql;
719 }
720 
BindFieldValue(sqlite3_stmt * statement,const QueryObjNode & queryNode,int & index) const721 int SqliteQueryHelper::BindFieldValue(sqlite3_stmt *statement, const QueryObjNode &queryNode, int &index) const
722 {
723     SymbolType symbolType = GetSymbolType(queryNode.operFlag);
724     if (symbolType != SymbolType::COMPARE_SYMBOL && symbolType != SymbolType::RELATIONAL_SYMBOL &&
725         symbolType != SymbolType::RANGE_SYMBOL) {
726         return E_OK;
727     }
728 
729     int errCode = SQLITE_OK;
730     for (size_t i = 0; i < queryNode.fieldValue.size(); i++) {
731         if (queryNode.type == QueryValueType::VALUE_TYPE_BOOL) {
732             errCode = sqlite3_bind_int(statement, index, queryNode.fieldValue[i].boolValue);
733         } else if (queryNode.type == QueryValueType::VALUE_TYPE_INTEGER) {
734             errCode = sqlite3_bind_int(statement, index, queryNode.fieldValue[i].integerValue);
735         } else if (queryNode.type == QueryValueType::VALUE_TYPE_LONG) {
736             errCode = sqlite3_bind_int64(statement, index, queryNode.fieldValue[i].longValue);
737         } else if (queryNode.type == QueryValueType::VALUE_TYPE_DOUBLE) {
738             errCode = sqlite3_bind_double(statement, index, queryNode.fieldValue[i].doubleValue);
739         } else {
740             if (queryNode.fieldValue[i].stringValue.size() > MAX_SQLITE_BIND_SIZE) {
741                 return -E_MAX_LIMITS;
742             }
743             errCode = sqlite3_bind_text(statement, index, queryNode.fieldValue[i].stringValue.c_str(),
744                 queryNode.fieldValue[i].stringValue.size(), SQLITE_TRANSIENT);
745         }
746         if (errCode != SQLITE_OK) {
747             break;
748         }
749         index++;
750     }
751     return SQLiteUtils::MapSQLiteErrno(errCode);
752 }
753 
GetFieldShape(const QueryObjNode & queryNode,const std::string & accessStr)754 std::string SqliteQueryHelper::GetFieldShape(const QueryObjNode &queryNode, const std::string &accessStr)
755 {
756     if (isRelationalQuery_) {
757         // For relational query, $. prefix is not permitted, so need not extract json. Return directly will be OK.
758         return "a.'" + queryNode.fieldName + "' ";
759     }
760     return MapCastFuncSql(queryNode, accessStr);
761 }
762 
ParseQueryExpression(const QueryObjNode & queryNode,std::string & querySql,const std::string & accessStr,bool placeholder)763 int SqliteQueryHelper::ParseQueryExpression(const QueryObjNode &queryNode, std::string &querySql,
764     const std::string &accessStr, bool placeholder)
765 {
766     SymbolType symbolType = GetSymbolType(queryNode.operFlag);
767     if (symbolType == SymbolType::RANGE_SYMBOL && queryNode.fieldValue.size() > MAX_CONDITIONS_SIZE) {
768         LOGE("[Query][Parse][Expression] conditions is too many!");
769         return -E_MAX_LIMITS;
770     }
771 
772     if (symbolType == SymbolType::COMPARE_SYMBOL || symbolType == SymbolType::RELATIONAL_SYMBOL ||
773         symbolType == SymbolType::RANGE_SYMBOL) {
774         querySql += GetFieldShape(queryNode, accessStr);
775         querySql += MapRelationalSymbolToSql(queryNode, placeholder);
776     } else if (symbolType == SymbolType::LOGIC_SYMBOL || symbolType == SymbolType::LINK_SYMBOL) {
777         querySql += MapLogicSymbolToSql(queryNode);
778     } else {
779         querySql += MapKeywordSymbolToSql(queryNode);
780     }
781 
782     if (querySql.size() > MAX_SQL_LEN) {
783         LOGE("[Query][Parse][Expression] Sql is too long!");
784         return -E_MAX_LIMITS;
785     }
786     return E_OK;
787 }
788 
AssembleSqlForSuggestIndex(const std::string & baseSql,const std::string & filter) const789 std::string SqliteQueryHelper::AssembleSqlForSuggestIndex(const std::string &baseSql, const std::string &filter) const
790 {
791     std::string formatIndex = CheckAndFormatSuggestIndex();
792     if (formatIndex.empty()) {
793         return baseSql + filter;
794     }
795 
796     return baseSql + USING_INDEX + "'" + formatIndex + "' " + filter;
797 }
798 
CheckAndFormatSuggestIndex() const799 std::string SqliteQueryHelper::CheckAndFormatSuggestIndex() const
800 {
801     if (suggestIndex_.empty()) {
802         return "";
803     }
804     IndexName indexName;
805     int errCode = SchemaUtils::ParseAndCheckFieldPath(suggestIndex_, indexName);
806     if (errCode != E_OK) {
807         LOGW("Check and format suggest index failed! %d", errCode);
808         return "";
809     }
810 
811     if (!schema_.IsIndexExist(indexName)) {
812         LOGW("The suggest index not exist!");
813         return "";
814     }
815     return SchemaUtils::FieldPathString(indexName);
816 }
817 
MapKeysInSubCondition(const std::string & accessStr) const818 std::string SqliteQueryHelper::MapKeysInSubCondition(const std::string &accessStr) const
819 {
820     std::string resultStr = "hex(" + accessStr + "key) IN (";
821     for (auto iter = keys_.begin(); iter != keys_.end(); iter++) {
822         if (iter != keys_.begin()) {
823             resultStr += ", ";
824         }
825         resultStr += "'" + DBCommon::VectorToHexString(*iter) + "' ";
826     }
827     resultStr += ")";
828     return resultStr;
829 }
830 
GetSubscribeCondition(const std::string & accessStr,std::string & conditionStr)831 int SqliteQueryHelper::GetSubscribeCondition(const std::string &accessStr, std::string &conditionStr)
832 {
833     if (queryObjNodes_.empty()) {
834         conditionStr += " (1 = 1) ";
835         return E_OK;
836     }
837 
838     bool hasQueryByValue = std::any_of(queryObjNodes_.begin(), queryObjNodes_.end(), [](const QueryObjNode &it) {
839         return GetSymbolType(it.operFlag) == SymbolType::COMPARE_SYMBOL ||
840             GetSymbolType(it.operFlag) == SymbolType::RELATIONAL_SYMBOL ||
841             GetSymbolType(it.operFlag) == SymbolType::RANGE_SYMBOL;
842     });
843     if (hasQueryByValue) {
844         // json_extract_by_path function will return error when value is empty, check it before when query by value
845         conditionStr += "((length(" + accessStr + "value) != 0 AND " + accessStr + "value IS NOT NULL) AND ";
846     } else {
847         conditionStr += "(";
848     }
849 
850     if (hasPrefixKey_) {
851         conditionStr += "(hex(" + accessStr + "key) LIKE '" + DBCommon::VectorToHexString(prefixKey_) + "%')";
852     }
853 
854     if (!keys_.empty()) {
855         if (hasPrefixKey_) {
856             conditionStr += " AND ";
857         }
858         conditionStr += "(" + MapKeysInSubCondition(accessStr) + ")";
859     }
860 
861     bool isNeedEndBracket = FilterSymbolToAddBracketLink(conditionStr, hasPrefixKey_ || !keys_.empty());
862     int errCode = E_OK;
863     for (const QueryObjNode &objNode : queryObjNodes_) {
864         SymbolType symbolType = GetSymbolType(objNode.operFlag);
865         if (symbolType == SymbolType::SPECIAL_SYMBOL && isNeedEndBracket) {
866             conditionStr += ") ";
867             isNeedEndBracket = false;
868         }
869         errCode = ParseQueryExpression(objNode, conditionStr, accessStr, false);
870         if (errCode != E_OK) {
871             conditionStr.clear();
872             return errCode;
873         }
874     }
875 
876     if (isNeedEndBracket) {
877         conditionStr += ") ";
878     }
879     conditionStr += ")";
880     return errCode;
881 }
882 
GetSubscribeSql(const std::string & subscribeId,TriggerModeEnum mode,std::string & subscribeCondition)883 int SqliteQueryHelper::GetSubscribeSql(const std::string &subscribeId, TriggerModeEnum mode,
884     std::string &subscribeCondition)
885 {
886     if (!isValid_) {
887         return -E_INVALID_QUERY_FORMAT;
888     }
889     int errCode = E_OK;
890     switch (mode) {
891         case TriggerModeEnum::INSERT:
892             errCode = GetSubscribeCondition(DBConstant::TRIGGER_REFERENCES_NEW, subscribeCondition);
893             break;
894         case TriggerModeEnum::UPDATE:
895             errCode = GetSubscribeCondition(DBConstant::TRIGGER_REFERENCES_OLD, subscribeCondition);
896             if (errCode != E_OK) {
897                 break;
898             }
899             subscribeCondition += " OR ";
900             errCode = GetSubscribeCondition(DBConstant::TRIGGER_REFERENCES_NEW, subscribeCondition);
901             break;
902         case TriggerModeEnum::DELETE:
903             errCode = GetSubscribeCondition(DBConstant::TRIGGER_REFERENCES_OLD, subscribeCondition);
904             break;
905         default:
906             errCode = -INVALID_ARGS;
907     }
908     if (errCode != E_OK) {
909         LOGD("Get subscribe query condition failed. %d", errCode);
910     }
911     return errCode;
912 }
913 
GetRelationalMissQuerySql(const std::vector<std::string> & fieldNames,std::string & sql)914 int SqliteQueryHelper::GetRelationalMissQuerySql(const std::vector<std::string> &fieldNames, std::string &sql)
915 {
916     if (!isValid_) {
917         return -E_INVALID_QUERY_FORMAT;
918     }
919 
920     if (hasPrefixKey_) {
921         LOGE("For relational DB query, prefix key is not supported.");
922         return -E_NOT_SUPPORT;
923     }
924 
925     sql = GetSelectAndFromClauseForRDB(tableName_, fieldNames);
926     sql += GetMissQueryFlagClauseForRDB();
927     sql += GetTimeRangeClauseForRDB();
928     sql += "ORDER BY " + DBConstant::TIMESTAMP_ALIAS + " ASC;";
929     return E_OK;
930 }
931 
GetRelationalSyncDataQuerySql(std::string & sql,bool hasSubQuery,const std::vector<std::string> & fieldNames)932 int SqliteQueryHelper::GetRelationalSyncDataQuerySql(std::string &sql, bool hasSubQuery,
933     const std::vector<std::string> &fieldNames)
934 {
935     if (!isValid_) {
936         return -E_INVALID_QUERY_FORMAT;
937     }
938 
939     if (hasPrefixKey_) {
940         LOGE("For relational DB query, prefix key is not supported.");
941         return -E_NOT_SUPPORT;
942     }
943 
944     sql = AssembleSqlForSuggestIndex(GetSelectAndFromClauseForRDB(tableName_, fieldNames), GetFlagClauseForRDB());
945     sql = hasSubQuery ? sql : (sql + GetTimeRangeClauseForRDB());
946 
947     querySql_.clear(); // clear local query sql format
948     int errCode = ToQuerySyncSql(hasSubQuery, true);
949     if (errCode != E_OK) {
950         LOGE("To query sql fail! errCode[%d]", errCode);
951         return errCode;
952     }
953     sql += querySql_;
954     if (hasSubQuery) {
955         // The last timestamp in one query will be stored in continue token and used for next query.
956         // Therefore all query data must be ordered by timestamp.
957         // When there is limit in SQL, data should be ordered by key in sub query, and timestamp is ordered by outside.
958         sql = GetOuterQueryClauseForRDB(sql);
959     }
960     return errCode;
961 }
962 
GetRelationalMissQueryStatement(sqlite3 * dbHandle,uint64_t beginTime,uint64_t endTime,const std::vector<std::string> & fieldNames,sqlite3_stmt * & statement)963 int SqliteQueryHelper::GetRelationalMissQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, uint64_t endTime,
964     const std::vector<std::string> &fieldNames, sqlite3_stmt *&statement)
965 {
966     std::string sql;
967     int errCode = GetRelationalMissQuerySql(fieldNames, sql);
968     if (errCode != E_OK) {
969         LOGE("[Query] Get SQL fail!");
970         return -E_INVALID_QUERY_FORMAT;
971     }
972 
973     errCode = SQLiteUtils::GetStatement(dbHandle, sql, statement);
974     if (errCode != E_OK) {
975         LOGE("[Query] Get statement fail!");
976         return -E_INVALID_QUERY_FORMAT;
977     }
978 
979     int index = 1; // begin with 1.
980     return BindTimeRange(statement, index, beginTime, endTime);
981 }
982 
983 namespace {
GetRelationalSyncDataQueryHeader(const std::vector<std::string> & fieldNames)984 std::string GetRelationalSyncDataQueryHeader(const std::vector<std::string> &fieldNames)
985 {
986     std::string sql = "SELECT b.data_key,"
987         "b.device,"
988         "b.ori_device,"
989         "b.timestamp as " + DBConstant::TIMESTAMP_ALIAS + ","
990         "b.wtimestamp,"
991         "b.flag,"
992         "b.hash_key,";
993     if (fieldNames.empty()) {  // For query check. If column count changed, can be discovered.
994         sql += "a.*";
995     } else {
996         for (const auto &fieldName : fieldNames) {  // For query data.
997             sql += "a." + fieldName + ",";
998         }
999         sql.pop_back();
1000     }
1001     return sql;
1002 }
1003 
GetRelationalCloudSyncDataQueryHeader(const std::vector<Field> & fields)1004 std::string GetRelationalCloudSyncDataQueryHeader(const std::vector<Field> &fields)
1005 {
1006     std::string sql = "SELECT b.data_key,"
1007         "b.device,"
1008         "b.ori_device,"
1009         "b.timestamp as " + DBConstant::TIMESTAMP_ALIAS + ","
1010         "b.wtimestamp,"
1011         "b.flag,"
1012         "b.hash_key,"
1013         "b.cloud_gid,"
1014         "b.version,";
1015     if (fields.empty()) {  // For query check. If column count changed, can be discovered.
1016         sql += "a.*";
1017     } else {
1018         for (const auto &field : fields) {  // For query data.
1019             sql += "a." + field.colName + ",";
1020         }
1021         sql.pop_back();
1022     }
1023     return sql;
1024 }
1025 }
1026 
GetRelationalSyncDataQuerySqlWithLimit(const std::vector<std::string> & fieldNames,std::string & sql)1027 int SqliteQueryHelper::GetRelationalSyncDataQuerySqlWithLimit(const std::vector<std::string> &fieldNames,
1028     std::string &sql)
1029 {
1030     if (!isValid_) {
1031         return -E_INVALID_QUERY_FORMAT;
1032     }
1033 
1034     if (hasPrefixKey_) {
1035         LOGE("For relational DB query, prefix key is not supported.");
1036         return -E_NOT_SUPPORT;
1037     }
1038     sql = GetRelationalSyncDataQueryHeader(fieldNames);
1039     sql += " FROM '" + tableName_ + "' AS a INNER JOIN ";
1040     sql += DBConstant::RELATIONAL_PREFIX + tableName_ + "_log";
1041     sql += " AS b ON (a." + std::string(DBConstant::SQLITE_INNER_ROWID) + " = b.data_key)";
1042     sql += " WHERE (b.flag&0x03=0x02)";
1043 
1044     querySql_.clear(); // clear local query sql format
1045     int errCode = ToQuerySyncSql(true, true);
1046     if (errCode != E_OK) {
1047         LOGE("To query sql fail! errCode[%d]", errCode);
1048         return errCode;
1049     }
1050     sql += querySql_;
1051     return E_OK;
1052 }
1053 
GetRelationalQueryStatement(sqlite3 * dbHandle,uint64_t beginTime,uint64_t endTime,const std::vector<std::string> & fieldNames,sqlite3_stmt * & statement)1054 int SqliteQueryHelper::GetRelationalQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, uint64_t endTime,
1055     const std::vector<std::string> &fieldNames, sqlite3_stmt *&statement)
1056 {
1057     int errCode = E_OK;
1058     bool hasSubQuery = false;
1059     std::string sql;
1060     if (hasLimit_ && !hasOrderBy_) { // Query with limit and no order by
1061         hasSubQuery = true; // Need sub query.
1062         errCode = GetRelationalSyncDataQuerySqlWithLimit(fieldNames, sql);
1063     } else if (hasLimit_ || hasOrderBy_) {
1064         hasSubQuery = true; // Need sub query.
1065         errCode = GetRelationalSyncDataQuerySql(sql, hasSubQuery, fieldNames);
1066     } else {
1067         isNeedOrderbyKey_ = false; // Need order by timestamp.
1068         errCode = GetRelationalSyncDataQuerySql(sql, hasSubQuery, fieldNames);
1069     }
1070     if (errCode != E_OK) {
1071         LOGE("[Query] Get SQL fail!");
1072         return -E_INVALID_QUERY_FORMAT;
1073     }
1074 
1075     errCode = SQLiteUtils::GetStatement(dbHandle, sql, statement);
1076     if (errCode != E_OK) {
1077         LOGE("[Query] Get statement fail!");
1078         return -E_INVALID_QUERY_FORMAT;
1079     }
1080 
1081     int index = 1; // begin with 1.
1082     if (hasSubQuery) {
1083         /**
1084          *   SELECT b.data_key,b.device,b.ori_device,b.timestamp as naturalbase_rdb_timestamp,
1085          *          b.wtimestamp,b.flag,b.hash_key,a.*
1086          *   FROM tableName AS a INNER JOIN naturalbase_rdb_log AS b
1087          *   ON a.rowid=b.data_key
1088          *   WHERE (b.flag&0x03=0x02)
1089          *   ORDER BY a.xxx
1090          *   LIMIT ? OFFSET ? )
1091          */
1092         errCode = BindObjNodes(statement, index);
1093         if (errCode != E_OK) {
1094             return errCode;
1095         }
1096         if (!hasLimit_ || hasOrderBy_) {
1097             errCode = BindTimeRange(statement, index, beginTime, endTime);
1098         }
1099     } else {
1100         /**
1101          * SELECT b.data_key,b.device,b.ori_device,b.timestamp as naturalbase_rdb_timestamp,
1102          *        b.wtimestamp,b.flag,b.hash_key,a.*
1103          * FROM tableName AS a INNER JOIN naturalbase_rdb_log AS b
1104          * ON a.rowid=b.data_key
1105          * WHERE (b.flag&0x03=0x02) AND (naturalbase_rdb_timestamp>=? AND naturalbase_rdb_timestamp<?)
1106          * ORDER BY naturalbase_rdb_timestamp ASC;
1107          */
1108         errCode = BindTimeRange(statement, index, beginTime, endTime);
1109         if (errCode != E_OK) {
1110             return errCode;
1111         }
1112         errCode = BindObjNodes(statement, index);
1113     }
1114     return errCode;
1115 }
1116 
MapKeysInToSql(size_t keysNum) const1117 std::string SqliteQueryHelper::MapKeysInToSql(size_t keysNum) const
1118 {
1119     std::string resultSql = "key IN (";
1120     for (size_t i = 0; i < keysNum; i++) {
1121         if (i != 0) {
1122             resultSql += ", ";
1123         }
1124         resultSql += "? ";
1125     }
1126     resultSql += ") ";
1127     return resultSql;
1128 }
1129 
BindKeysToStmt(const std::set<Key> & keys,sqlite3_stmt * & statement,int & index) const1130 int SqliteQueryHelper::BindKeysToStmt(const std::set<Key> &keys, sqlite3_stmt *&statement, int &index) const
1131 {
1132     if (!keys_.empty()) {
1133         int errCode = E_OK;
1134         for (const auto &key : keys) {
1135             errCode = SQLiteUtils::BindBlobToStatement(statement, index, key);
1136             if (errCode != E_OK) {
1137                 LOGE("[Query] Get statement when bind keys failed, errCode = %d", errCode);
1138                 return errCode;
1139             }
1140             index++;
1141         }
1142     }
1143     return E_OK;
1144 }
1145 
GetRelationalCloudQueryStatement(sqlite3 * dbHandle,uint64_t beginTime,const std::vector<Field> & fields,const bool & isCloudForcePush,sqlite3_stmt * & statement)1146 int SqliteQueryHelper::GetRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime,
1147     const std::vector<Field> &fields, const bool &isCloudForcePush, sqlite3_stmt *&statement)
1148 {
1149     std::string sql = GetRelationalCloudSyncDataQueryHeader(fields);
1150     AppendCloudQuery(isCloudForcePush, sql);
1151     return GetCloudQueryStatement(true, dbHandle, beginTime, sql, statement);
1152 }
1153 
GetCountRelationalCloudQueryStatement(sqlite3 * dbHandle,uint64_t beginTime,bool isCloudForcePush,sqlite3_stmt * & statement)1154 int SqliteQueryHelper::GetCountRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime,
1155     bool isCloudForcePush, sqlite3_stmt *&statement)
1156 {
1157     std::string sql = "SELECT COUNT(*) ";
1158     AppendCloudQuery(isCloudForcePush, sql);
1159     return GetCloudQueryStatement(false, dbHandle, beginTime, sql, statement);
1160 }
1161 
GetGidRelationalCloudQueryStatement(sqlite3 * dbHandle,uint64_t beginTime,const std::vector<Field> & fields,bool isCloudForcePush,sqlite3_stmt * & statement)1162 int SqliteQueryHelper::GetGidRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime,
1163     const std::vector<Field> &fields, bool isCloudForcePush, sqlite3_stmt *&statement)
1164 {
1165     std::string sql = GetRelationalCloudSyncDataQueryHeader(fields);
1166     AppendCloudGidQuery(isCloudForcePush, sql);
1167     return GetCloudQueryStatement(false, dbHandle, beginTime, sql, statement);
1168 }
1169 
AppendCloudQuery(bool isCloudForcePush,std::string & sql)1170 void SqliteQueryHelper::AppendCloudQuery(bool isCloudForcePush, std::string &sql)
1171 {
1172     sql += CloudStorageUtils::GetLeftJoinLogSql(tableName_, false);
1173     sql += isCloudForcePush ? " WHERE b.timestamp > ? AND (b.flag & 0x04 != 0x04)" :
1174         " WHERE b.timestamp > ? AND (b.flag & 0x02 = 0x02)";
1175     sql += " AND (b.flag & 0x08 != 0x08) AND (b.cloud_gid != '' or"; // actually, b.cloud_gid will not be null.
1176     sql += " (b.cloud_gid == '' and (b.flag & 0x01 = 0))) ";
1177 }
1178 
AppendCloudGidQuery(bool isCloudForcePush,std::string & sql)1179 void SqliteQueryHelper::AppendCloudGidQuery(bool isCloudForcePush, std::string &sql)
1180 {
1181     sql += CloudStorageUtils::GetLeftJoinLogSql(tableName_, false);
1182     sql += isCloudForcePush ? " WHERE b.timestamp > ? AND (b.flag & 0x04 != 0x04)" :
1183         " WHERE b.timestamp > ?";
1184     sql += " AND (b.cloud_gid != '') "; // actually, b.cloud_gid will not be null.
1185 }
1186 
GetCloudQueryStatement(bool useTimestampAlias,sqlite3 * dbHandle,uint64_t beginTime,std::string & sql,sqlite3_stmt * & statement)1187 int SqliteQueryHelper::GetCloudQueryStatement(bool useTimestampAlias, sqlite3 *dbHandle, uint64_t beginTime,
1188     std::string &sql, sqlite3_stmt *&statement)
1189 {
1190     querySql_.clear(); // clear local query sql format
1191     int errCode = ToQuerySyncSql(false, useTimestampAlias);
1192     if (errCode != E_OK) {
1193         LOGE("To query sql fail! errCode[%d]", errCode);
1194         return errCode;
1195     }
1196     sql += querySql_;
1197     errCode = SQLiteUtils::GetStatement(dbHandle, sql, statement);
1198     if (errCode != E_OK) {
1199         LOGE("[Query] Get statement fail!");
1200         return -E_INVALID_QUERY_FORMAT;
1201     }
1202     errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, static_cast<int64_t>(beginTime));
1203     if (errCode != E_OK) {
1204         int resetRet = E_OK;
1205         SQLiteUtils::ResetStatement(statement, true, resetRet);
1206         if (resetRet != E_OK) {
1207             LOGW("[Query] reset statement failed %d", resetRet);
1208         }
1209         return errCode;
1210     }
1211     int index = 2;
1212     errCode = BindObjNodes(statement, index);
1213     if (errCode != E_OK) {
1214         LOGE("[Query] BindObjNodes failed %d", errCode);
1215         int resetRet = E_OK;
1216         SQLiteUtils::ResetStatement(statement, true, errCode);
1217         if (resetRet != E_OK) {
1218             LOGW("[Query] reset statement failed %d", resetRet);
1219         }
1220     }
1221     return errCode;
1222 }
1223 }