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 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17 
18 #include "db_common.h"
19 #include "db_errno.h"
20 #include "db_types.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "kvdb_properties.h"
24 #include "log_print.h"
25 #include "prepared_stmt.h"
26 #include "relational_row_data_set.h"
27 #include "relational_store_delegate.h"
28 #include "relational_store_instance.h"
29 #include "relational_store_manager.h"
30 #include "relational_store_sqlite_ext.h"
31 #include "relational_sync_able_storage.h"
32 #include "sqlite_relational_store.h"
33 #include "sqlite_utils.h"
34 #include "virtual_communicator_aggregator.h"
35 
36 using namespace testing::ext;
37 using namespace DistributedDB;
38 using namespace DistributedDBUnitTest;
39 using namespace std;
40 
41 namespace {
42 string g_testDir;
43 string g_storePath;
44 string g_storeID = "dftStoreID";
45 string g_tableName { "data" };
46 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
47 RelationalStoreDelegate *g_delegate = nullptr;
48 IRelationalStore *g_store = nullptr;
49 
CreateDBAndTable()50 void CreateDBAndTable()
51 {
52     sqlite3 *db = nullptr;
53     int errCode = sqlite3_open(g_storePath.c_str(), &db);
54     if (errCode != SQLITE_OK) {
55         LOGE("open db failed:%d", errCode);
56         sqlite3_close(db);
57         return;
58     }
59 
60     const string sql =
61         "PRAGMA journal_mode=WAL;"
62         "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
63     char *zErrMsg = nullptr;
64     errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &zErrMsg);
65     if (errCode != SQLITE_OK) {
66         LOGE("sql error:%s", zErrMsg);
67         sqlite3_free(zErrMsg);
68     }
69     sqlite3_close(db);
70 }
71 
InitStoreProp(const std::string & storePath,const std::string & appId,const std::string & userId,RelationalDBProperties & properties)72 void InitStoreProp(const std::string &storePath, const std::string &appId, const std::string &userId,
73     RelationalDBProperties &properties)
74 {
75     properties.SetStringProp(RelationalDBProperties::DATA_DIR, storePath);
76     properties.SetStringProp(RelationalDBProperties::APP_ID, appId);
77     properties.SetStringProp(RelationalDBProperties::USER_ID, userId);
78     properties.SetStringProp(RelationalDBProperties::STORE_ID, g_storeID);
79     std::string identifier = userId + "-" + appId + "-" + g_storeID;
80     std::string hashIdentifier = DBCommon::TransferHashString(identifier);
81     properties.SetStringProp(RelationalDBProperties::IDENTIFIER_DATA, hashIdentifier);
82 }
83 
GetRelationalStore()84 const RelationalSyncAbleStorage *GetRelationalStore()
85 {
86     RelationalDBProperties properties;
87     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
88     int errCode = E_OK;
89     g_store = RelationalStoreInstance::GetDataBase(properties, errCode);
90     if (g_store == nullptr) {
91         LOGE("Get db failed:%d", errCode);
92         return nullptr;
93     }
94     return static_cast<SQLiteRelationalStore *>(g_store)->GetStorageEngine();
95 }
96 
ExecSql(sqlite3 * db,const std::string & sql)97 int ExecSql(sqlite3 *db, const std::string &sql)
98 {
99     return sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
100 }
101 
InsertData(sqlite3 * db,size_t byteSize)102 int InsertData(sqlite3 *db, size_t byteSize)
103 {
104     static const std::string sql = "INSERT OR REPLACE INTO " + g_tableName + " VALUES(?,?);";
105     sqlite3_stmt *stmt = nullptr;
106     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
107     if (errCode != E_OK) {
108         return errCode;
109     }
110     std::vector<uint8_t> value(byteSize);
111     errCode = SQLiteUtils::BindBlobToStatement(stmt, 2, value, false);  // 2 means value's index.
112     if (errCode != E_OK) {
113         return errCode;
114     }
115     errCode = SQLiteUtils::StepWithRetry(stmt);
116     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
117         errCode = E_OK;
118     }
119     SQLiteUtils::ResetStatement(stmt, true, errCode);
120     return errCode;
121 }
122 }
123 
124 class DistributedDBRelationalRemoteQueryTest : public testing::Test {
125 public:
126     static void SetUpTestCase();
127     static void TearDownTestCase();
128     void SetUp();
129     void TearDown();
130 };
131 
SetUpTestCase(void)132 void DistributedDBRelationalRemoteQueryTest::SetUpTestCase(void)
133 {
134     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
135     g_storePath = g_testDir + "/relationalRemoteQueryTest.db";
136     LOGI("The test db is:%s", g_testDir.c_str());
137 
138     auto communicator = new (std::nothrow) VirtualCommunicatorAggregator();
139     ASSERT_TRUE(communicator != nullptr);
140     RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicator);
141 }
142 
TearDownTestCase(void)143 void DistributedDBRelationalRemoteQueryTest::TearDownTestCase(void)
144 {
145     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
146 }
147 
SetUp(void)148 void DistributedDBRelationalRemoteQueryTest::SetUp(void)
149 {
150     g_tableName = "data";
151     DistributedDBToolsUnitTest::PrintTestCaseInfo();
152     CreateDBAndTable();
153 }
154 
TearDown(void)155 void DistributedDBRelationalRemoteQueryTest::TearDown(void)
156 {
157     if (g_delegate != nullptr) {
158         EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
159         g_delegate = nullptr;
160     }
161     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
162         LOGE("rm test db files error.");
163     }
164     return;
165 }
166 
167 /**
168  * @tc.name: NormalQuery1
169  * @tc.desc: Normal query.
170  * @tc.type: FUNC
171  * @tc.require: AR000GK58G
172  * @tc.author: lidongwei
173  */
174 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NormalQuery1, TestSize.Level1)
175 {
176     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
177     ASSERT_NE(g_delegate, nullptr);
178     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
179 
180     /**
181      * @tc.steps: step1. Put data.
182      * @tc.expected: Succeed, return OK.
183      */
184     sqlite3 *db = nullptr;
185     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
186     ASSERT_NE(db, nullptr);
187 
188     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"), 0);
189     sqlite3_close(db);
190 
191     /**
192      * @tc.steps: step2. Query with QUERY opcode and a select sql.
193      * @tc.expected: Query successfully.
194      */
195     auto store = GetRelationalStore();
196 
197     ASSERT_NE(store, nullptr);
198     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
199     RelationalRowDataSet rowDataSet {};
200     ContinueToken token = nullptr;
201     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
202     EXPECT_EQ(rowDataSet.GetSize(), 1);
203     EXPECT_EQ(token, nullptr);
204     RefObject::DecObjRef(g_store);
205 }
206 
207 /**
208  * @tc.name: NormalQuery1
209  * @tc.desc: test sql len is larger than 100,0000
210  * @tc.type: FUNC
211  * @tc.require: AR000GK58G
212  * @tc.author: zhuwentao
213  */
214 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NormalQuery2, TestSize.Level1)
215 {
216     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
217     ASSERT_NE(g_delegate, nullptr);
218     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
219     std::string device = "deviceB";
220     RemoteCondition sqlCondition;
221     sqlCondition.sql.resize(1000001, 'a');
222     std::shared_ptr<ResultSet> result = nullptr;
223     EXPECT_EQ(g_delegate->RemoteQuery(device, sqlCondition, 5000, result), OVER_MAX_LIMITS);
224 }
225 
226 /**
227  * @tc.name: BoolQuery1
228  * @tc.desc: Query bool.
229  * @tc.type: FUNC
230  * @tc.require: AR000GK58G
231  * @tc.author: lidongwei
232  */
233 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BoolQuery1, TestSize.Level1)
234 {
235     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
236     ASSERT_NE(g_delegate, nullptr);
237     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
238 
239     /**
240      * @tc.steps: step1. Put data.
241      * @tc.expected: Succeed, return OK.
242      */
243     sqlite3 *db = nullptr;
244     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
245     ASSERT_NE(db, nullptr);
246 
247     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"), 0);
248     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(2, '1');"), 0);
249     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(3, true);"), 0);
250     sqlite3_close(db);
251 
252     /**
253      * @tc.steps: step2. Check bool.
254      * @tc.expected: '1' and 1 and true in sql is OK. 1 in bindArgs is OK.
255      */
256     auto store = GetRelationalStore();
257     ASSERT_NE(store, nullptr);
258 
259     RelationalRowDataSet rowDataSet {};
260     ContinueToken token = nullptr;
261 
262     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"1"});
263     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
264     EXPECT_EQ(rowDataSet.GetSize(), 3);
265 
266     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='1'", {} };
267     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
268     EXPECT_EQ(rowDataSet.GetSize(), 3);
269 
270     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=1", {} };
271     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
272     EXPECT_EQ(rowDataSet.GetSize(), 3);
273 
274     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=true", {} };
275     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
276     EXPECT_EQ(rowDataSet.GetSize(), 3);
277 
278     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"'1'"} };
279     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
280     EXPECT_EQ(rowDataSet.GetSize(), 0);
281 
282     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='true'", {} };
283     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
284     EXPECT_EQ(rowDataSet.GetSize(), 0);
285 
286     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"true"} };
287     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
288     EXPECT_EQ(rowDataSet.GetSize(), 0);
289 
290     RefObject::DecObjRef(g_store);
291 }
292 
293 /**
294  * @tc.name: BlobQuery1
295  * @tc.desc: Query blob.
296  * @tc.type: FUNC
297  * @tc.require: AR000GK58G
298  * @tc.author: lidongwei
299  */
300 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BlobQuery1, TestSize.Level1)
301 {
302     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
303     ASSERT_NE(g_delegate, nullptr);
304     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
305 
306     /**
307      * @tc.steps: step1. Put data.
308      * @tc.expected: Succeed, return OK.
309      */
310     sqlite3 *db = nullptr;
311     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
312     ASSERT_NE(db, nullptr);
313 
314     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
315     sqlite3_close(db);
316 
317     /**
318      * @tc.steps: step2. Check blob.
319      * @tc.expected: x'xxx' in sql is OK. Not ok in bindArgs.
320      */
321     auto store = GetRelationalStore();
322     ASSERT_NE(store, nullptr);
323 
324     RelationalRowDataSet rowDataSet {};
325     ContinueToken token = nullptr;
326 
327     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000'", {});
328     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
329     EXPECT_EQ(rowDataSet.GetSize(), 1);
330     EXPECT_FALSE(rowDataSet.GetColNames().empty());
331 
332     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"x'10101010001000'"} };
333     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
334     EXPECT_EQ(rowDataSet.GetSize(), 0);
335     EXPECT_TRUE(rowDataSet.GetColNames().empty());
336 
337     RefObject::DecObjRef(g_store);
338 }
339 
340 /**
341  * @tc.name: InsertQuery1
342  * @tc.desc: Query with insert statement.
343  * @tc.type: FUNC
344  * @tc.require: AR000GK58G
345  * @tc.author: lidongwei
346  */
347 HWTEST_F(DistributedDBRelationalRemoteQueryTest, InsertQuery1, TestSize.Level1)
348 {
349     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
350     ASSERT_NE(g_delegate, nullptr);
351     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
352 
353     /**
354      * @tc.steps: step1. Put data.
355      * @tc.expected: Succeed, return OK.
356      */
357     sqlite3 *db = nullptr;
358     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
359     ASSERT_NE(db, nullptr);
360 
361     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
362     sqlite3_close(db);
363 
364     /**
365      * @tc.steps: step2. Query with a insert statement.
366      * @tc.expected: Query failed.
367      */
368     auto store = GetRelationalStore();
369     ASSERT_NE(store, nullptr);
370 
371     RelationalRowDataSet rowDataSet {};
372     ContinueToken token = nullptr;
373 
374     /**
375      * @tc.steps: step3. Query with INSERT opcode.
376      * @tc.expected: Query failed. Return E_INVALID_ARGS.
377      */
378     PreparedStmt prepStmt(PreparedStmt::INSERT, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {});
379     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_INVALID_ARGS);
380     EXPECT_EQ(rowDataSet.GetSize(), 0);
381 
382     /**
383      * @tc.steps: step4. Query with QUERY opcode and a insert sql.
384      * @tc.expected: Query failed. Return E_DENIED_SQL.
385      */
386     prepStmt = { PreparedStmt::QUERY, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
387     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_DENIED_SQL);
388     EXPECT_EQ(rowDataSet.GetSize(), 0);
389 
390     /**
391      * @tc.steps: step5. Query with QUERY opcode and two sql(one select and one insert).
392      * @tc.expected: Query OK. The second sql is ignored.
393      */
394     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000';"
395                                       "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
396     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
397     EXPECT_EQ(rowDataSet.GetSize(), 1);
398 
399     RefObject::DecObjRef(g_store);
400 }
401 
402 /**
403  * @tc.name: NonexistentTable1
404  * @tc.desc: Nonexistent table or column.
405  * @tc.type: FUNC
406  * @tc.require: AR000GK58G
407  * @tc.author: lidongwei
408  */
409 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NonexistentTable1, TestSize.Level1)
410 {
411     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
412     ASSERT_NE(g_delegate, nullptr);
413     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
414 
415     /**
416      * @tc.steps: step1. Query when nonexistent table or nonexistent column.
417      * @tc.expected: Failed, return SQLITE_ERROR
418      */
419     auto store = GetRelationalStore();
420     ASSERT_NE(store, nullptr);
421 
422     RelationalRowDataSet rowDataSet {};
423     ContinueToken token = nullptr;
424 
425     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM nonexistent_table WHERE value=1;", {});
426     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
427 
428     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE nonexistent_column=1;", {} };
429     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
430 
431     RefObject::DecObjRef(g_store);
432 }
433 
434 /**
435  * @tc.name: PreparedStmtSerialize
436  * @tc.desc: Test the serialization and deserialization of PreparedStmt.
437  * @tc.type: FUNC
438  * @tc.require: AR000GK58G
439  * @tc.author: lidongwei
440  */
441 HWTEST_F(DistributedDBRelationalRemoteQueryTest, PreparedStmtSerialize, TestSize.Level1)
442 {
443     /**
444      * @tc.steps: step1. Create a prepared stmt;
445      * @tc.expected: OK.
446      */
447     PreparedStmt prepStmt1(PreparedStmt::QUERY, "SELECT * FROM test WHERE value=? or value=?", {"1", "2"});
448     int len = static_cast<int>(prepStmt1.CalcLength());
449 
450     /**
451      * @tc.steps: step2. Serialize the prepared stmt;
452      * @tc.expected: Serialize OK.
453      */
454     std::vector<uint8_t> buffer(len);
455     Parcel parcel1(buffer.data(), buffer.size());
456     ASSERT_EQ(prepStmt1.Serialize(parcel1), E_OK);
457     ASSERT_FALSE(parcel1.IsError());
458 
459     /**
460      * @tc.steps: step3. Deserialize the prepared stmt;
461      * @tc.expected: Deserialize OK.
462      */
463     PreparedStmt prepStmt2;
464     Parcel parcel2(buffer.data(), buffer.size());
465     ASSERT_EQ(prepStmt2.DeSerialize(parcel2), E_OK);
466     ASSERT_FALSE(parcel2.IsError());
467 
468     /**
469      * @tc.steps: step4. Compare the deserialized prepared stmt with the original;
470      * @tc.expected: Compare OK. They are the same.
471      */
472     EXPECT_EQ(prepStmt1.GetOpCode(), prepStmt2.GetOpCode());
473     EXPECT_EQ(prepStmt1.GetSql(), prepStmt2.GetSql());
474     EXPECT_EQ(prepStmt1.GetBindArgs(), prepStmt2.GetBindArgs());
475 }
476 
477 /**
478  * @tc.name: ComplexQuery1
479  * @tc.desc: Complex query with join or aggregate func.
480  * @tc.type: FUNC
481  * @tc.require: AR000GK58G
482  * @tc.author: lidongwei
483  */
484 HWTEST_F(DistributedDBRelationalRemoteQueryTest, ComplexQuery1, TestSize.Level1)
485 {
486     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
487     ASSERT_NE(g_delegate, nullptr);
488     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
489 
490     sqlite3 *db = nullptr;
491     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
492     ASSERT_NE(db, nullptr);
493 
494     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"
495                           "CREATE TABLE IF NOT EXISTS r(key INTEGER, value INTEGER);"
496                           "INSERT INTO r VALUES(1, 1);"), 0);
497     sqlite3_close(db);
498 
499     /**
500      * @tc.steps: step1. Query with a complex sql.
501      * @tc.expected: Succeed.
502      */
503     auto store = GetRelationalStore();
504     ASSERT_NE(store, nullptr);
505 
506     RelationalRowDataSet rowDataSet {};
507     ContinueToken token = nullptr;
508 
509     PreparedStmt prepStmt(PreparedStmt::QUERY,
510         "SELECT COUNT(*) FROM " + g_tableName + " INNER JOIN r ON " + g_tableName + ".key=r.key "
511         "WHERE r.value IN (1,2,3);", {});
512     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
513     EXPECT_EQ(rowDataSet.GetSize(), 1);
514 
515     RefObject::DecObjRef(g_store);
516 }
517 
518 /**
519  * @tc.name: LargeAmountOfData1
520  * @tc.desc: Large Amount Of Data.
521  * @tc.type: FUNC
522  * @tc.require: AR000GK58G
523  * @tc.author: lidongwei
524  */
525 HWTEST_F(DistributedDBRelationalRemoteQueryTest, LargeAmountOfData1, TestSize.Level1)
526 {
527     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
528     ASSERT_NE(g_delegate, nullptr);
529     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
530 
531     sqlite3 *db = nullptr;
532     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
533     ASSERT_NE(db, nullptr);
534 
535     /**
536      * @tc.steps: step1. Insert 20 data.
537      * @tc.expected: Succeed.
538      */
539     int i = 10;  // 10 for test.
540     while (i-- > 0) {
541         ASSERT_EQ(InsertData(db, 500), 0);  // 500 for test.
542         ASSERT_EQ(InsertData(db, 1500), 0); // 1500 for test.
543     }
544     sqlite3_close(db);
545 
546     /**
547      * @tc.steps: step2. Query.
548      * @tc.expected: Get 20 data.
549      */
550     auto store = GetRelationalStore();
551     ASSERT_NE(store, nullptr);
552 
553     ContinueToken token = nullptr;
554     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
555 
556     size_t totalCnt = 0;
557     RelationalRowDataSet allRowDataSet {};
558     do {
559         RelationalRowDataSet rowDataSet {};
560         EXPECT_EQ(store->ExecuteQuery(prepStmt, 1024, rowDataSet, token), E_OK);  // 1024 is min mtu.
561         totalCnt += static_cast<size_t>(rowDataSet.GetSize());
562         EXPECT_EQ(allRowDataSet.Merge(std::move(rowDataSet)), E_OK);
563     } while (token != nullptr);
564 
565     EXPECT_EQ(totalCnt, 20u);
566     EXPECT_EQ(allRowDataSet.GetSize(), 20);
567 
568     RefObject::DecObjRef(g_store);
569 }
570 
571 /**
572  * @tc.name: OverSize1
573  * @tc.desc: Over size.
574  * @tc.type: FUNC
575  * @tc.require: AR000GK58G
576  * @tc.author: lidongwei
577  */
578 HWTEST_F(DistributedDBRelationalRemoteQueryTest, OverSize1, TestSize.Level1)
579 {
580     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
581     ASSERT_NE(g_delegate, nullptr);
582     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
583 
584     sqlite3 *db = nullptr;
585     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
586     ASSERT_NE(db, nullptr);
587 
588     /**
589      * @tc.steps: step1. Insert over 4M data.
590      * @tc.expected: Succeed.
591      */
592     int i = 4;  // 4MB
593     while (i-- > 0) {
594         ASSERT_EQ(InsertData(db, 1024 * 1024), 0);  // 1024*1024 means 1MB.
595     }
596     sqlite3_close(db);
597 
598     /**
599      * @tc.steps: step2. Query.
600      * @tc.expected: Failed, return E_REMOTE_OVER_SIZE.
601      */
602     auto store = GetRelationalStore();
603     ASSERT_NE(store, nullptr);
604 
605     ContinueToken token = nullptr;
606     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
607 
608     RelationalRowDataSet rowDataSet {};
609     EXPECT_EQ(store->ExecuteQuery(prepStmt, 1200, rowDataSet, token), -E_REMOTE_OVER_SIZE);
610     RefObject::DecObjRef(g_store);
611 }
612 
613 /**
614  * @tc.name: RemoteQueryForNotDistributedDb
615  * @tc.desc: Not create distributed table, exec remote query.
616  * @tc.type: FUNC
617  * @tc.require: AR000GK58G
618  * @tc.author: lidongwei
619  */
620 HWTEST_F(DistributedDBRelationalRemoteQueryTest, RemoteQueryForNotDistributedDb, TestSize.Level1)
621 {
622     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
623     ASSERT_NE(g_delegate, nullptr);
624 
625     std::shared_ptr<ResultSet> result = nullptr;
626     EXPECT_EQ(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, 1000, result), DBStatus::NOT_SUPPORT);
627 }
628 #endif
629