1 /*
2  * Copyright (c) 2023 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 
16 #include <gtest/gtest.h>
17 #include <queue>
18 #include <random>
19 
20 #include "cloud_db_sync_utils_test.h"
21 #include "cloud/cloud_db_types.h"
22 #include "db_common.h"
23 #include "distributeddb_data_generate_unit_test.h"
24 #include "distributeddb_tools_unit_test.h"
25 #include "log_print.h"
26 #include "platform_specific.h"
27 #include "relational_store_manager.h"
28 #include "relational_store_sqlite_ext.h"
29 #include "relational_virtual_device.h"
30 #include "runtime_config.h"
31 #include "virtual_relational_ver_sync_db_interface.h"
32 
33 using namespace testing::ext;
34 using namespace DistributedDB;
35 using namespace DistributedDBUnitTest;
36 using namespace std;
37 
38 namespace {
39     constexpr const char *DB_SUFFIX = ".db";
40     constexpr const char *STORE_ID = "Relational_Store_tracker";
41     constexpr const char *STORE_ID2 = "Relational_Store_tracker2";
42     std::string g_testDir;
43     std::string g_dbDir;
44     const string TABLE_NAME1 = "worKer1";
45     const string TABLE_NAME2 = "worKer2";
46     const string TABLE_NAME3 = "worKer3";
47     DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
48     RelationalStoreDelegate *g_delegate = nullptr;
49     sqlite3 *g_db = nullptr;
50     const int HALF = 2;
51 
52     const std::string CREATE_LOCAL_TABLE_SQL =
53     "CREATE TABLE IF NOT EXISTS " + TABLE_NAME1 + "(" \
54     "name TEXT PRIMARY KEY," \
55     "height REAL ," \
56     "married BOOLEAN ," \
57     "photo BLOB NOT NULL," \
58     "assert BLOB," \
59     "age INT);";
60 
61     const std::string CREATE_LOCAL_PK_TABLE_SQL =
62     "CREATE TABLE IF NOT EXISTS " + TABLE_NAME2 + "(" \
63     "id INTEGER PRIMARY KEY AUTOINCREMENT," \
64     "name TEXT ," \
65     "height REAL ," \
66     "photo BLOB ," \
67     "asserts BLOB," \
68     "age INT);";
69 
70     const std::string CREATE_LOCAL_PK_TABLE_SQL2 =
71     "CREATE TABLE IF NOT EXISTS " + TABLE_NAME3 + "(" \
72     "id INTEGER PRIMARY KEY," \
73     "name asseT ," \
74     "age ASSETs);";
75 
76     const std::string EXTEND_COL_NAME1 = "xxx";
77     const std::string EXTEND_COL_NAME2 = "name";
78     const std::string EXTEND_COL_NAME3 = "age";
79     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET1 = { "name1" };
80     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET2 = { "name" };
81     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET3 = { "height" };
82     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET4 = { "height", "name" };
83     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET5 = { "name", "" };
84     TrackerSchema g_normalSchema1 = {
85         .tableName = TABLE_NAME2, .extendColName = EXTEND_COL_NAME2, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2
86     };
87     TrackerSchema g_normalSchema2 = {
88         .tableName = TABLE_NAME2, .extendColName = EXTEND_COL_NAME3, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2
89     };
90     TrackerSchema g_normalSchema3 = {
91         .tableName = TABLE_NAME2, .extendColName = EXTEND_COL_NAME3, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET4
92     };
93 
CreateMultiTable()94     void CreateMultiTable()
95     {
96         g_db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
97         ASSERT_NE(g_db, nullptr);
98         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
99         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_TABLE_SQL), SQLITE_OK);
100         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
101         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL2), SQLITE_OK);
102     }
103 
BatchInsertTableName2Data(uint64_t num)104     void BatchInsertTableName2Data(uint64_t num)
105     {
106         for (size_t i = 0; i < num; i++) {
107             string sql = "INSERT INTO " + TABLE_NAME2
108                 + " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(i) +
109                 "', '175.8', 175.88888888888, 'x', '18');";
110             EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
111         }
112     }
113 
BatchUpdateTableName2Data(uint64_t num,const std::set<std::string> & colNames)114     void BatchUpdateTableName2Data(uint64_t num, const std::set<std::string> &colNames)
115     {
116         std::string sql = "UPDATE " + TABLE_NAME2 + " SET ";
117         for (const auto &col: colNames) {
118             sql += col + " = '1',";
119         }
120         sql.pop_back();
121         sql += " where id = ";
122         for (size_t i = 1; i <= num; i++) {
123             EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql + std::to_string(i)), SQLITE_OK);
124         }
125     }
126 
BatchDeleteTableName2Data(uint64_t num)127     void BatchDeleteTableName2Data(uint64_t num)
128     {
129         std::string sql = "DELETE FROM " + TABLE_NAME2 + " WHERE id <= " + std::to_string(num);
130         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
131     }
132 
BatchOperatorTableName2Data(uint64_t num,const std::set<std::string> & colNames)133     void BatchOperatorTableName2Data(uint64_t num, const std::set<std::string> &colNames)
134     {
135         for (int i = 0; i < HALF; i++) {
136             BatchInsertTableName2Data(num);
137         }
138         BatchUpdateTableName2Data(num, colNames);
139         BatchDeleteTableName2Data(num);
140     }
141 
CheckExtendAndCursor(uint64_t num,int start)142     void CheckExtendAndCursor(uint64_t num, int start)
143     {
144         int index = 0;
145         string querySql = "select extend_field, cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
146             " where data_key <= " + std::to_string(num);
147         sqlite3_stmt *stmt = nullptr;
148         EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
149         while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
150             std::string extendVal;
151             EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
152             ASSERT_NE(num, 0u);
153             EXPECT_EQ(extendVal, "Local" + std::to_string(index % num));
154             std::string cursorVal;
155             EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
156             EXPECT_EQ(cursorVal, std::to_string(num + (++index) + start));
157         }
158         int errCode;
159         SQLiteUtils::ResetStatement(stmt, true, errCode);
160     }
161 
OpenStore()162     void OpenStore()
163     {
164         if (g_db == nullptr) {
165             g_db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
166             ASSERT_NE(g_db, nullptr);
167         }
168         DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, g_delegate);
169         EXPECT_EQ(status, OK);
170         ASSERT_NE(g_delegate, nullptr);
171     }
172 
CloseStore()173     void CloseStore()
174     {
175         if (g_db != nullptr) {
176             EXPECT_EQ(sqlite3_close_v2(g_db), SQLITE_OK);
177             g_db = nullptr;
178         }
179         if (g_delegate != nullptr) {
180             EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
181             g_delegate = nullptr;
182         }
183     }
184 
CheckDropTableAndReopenDb(bool isDistributed)185     void CheckDropTableAndReopenDb(bool isDistributed)
186     {
187         /**
188          * @tc.steps:step1. SetTrackerTable, init data and drop table
189          * @tc.expected: step1. Return OK.
190          */
191         CreateMultiTable();
192         OpenStore();
193         if (isDistributed) {
194             EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
195         }
196         TrackerSchema schema = g_normalSchema1;
197         EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
198         uint64_t num = 10;
199         BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
200         std::string sql = "drop table if exists " + TABLE_NAME2;
201         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
202         CloseStore();
203 
204         /**
205          * @tc.steps:step2. reopen db, check log table
206          * @tc.expected: step2. Return OK.
207          */
208         OpenStore();
209         sql = "select count(*) from sqlite_master where name = '" + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 +
210             "_log'";
211         EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
212             reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
213 
214         /**
215          * @tc.steps:step3. check tracker schema
216          * @tc.expected: step3. Return OK.
217          */
218         const Key schemaKey(DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.begin(),
219             DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.end());
220         sql = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + "metadata WHERE key=?;";
221         sqlite3_stmt *stmt = nullptr;
222         EXPECT_EQ(SQLiteUtils::GetStatement(g_db, sql, stmt), E_OK);
223         EXPECT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, schemaKey, false), E_OK);
224         Value schemaVal;
225         while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
226             SQLiteUtils::GetColumnBlobValue(stmt, 0, schemaVal);
227         }
228         EXPECT_TRUE(schemaVal.size() != 0);
229         int errCode;
230         SQLiteUtils::ResetStatement(stmt, true, errCode);
231         std::string schemaStr;
232         DBCommon::VectorToString(schemaVal, schemaStr);
233         RelationalSchemaObject schemaObject;
234         EXPECT_EQ(schemaObject.ParseFromTrackerSchemaString(schemaStr), E_OK);
235         EXPECT_EQ(schemaObject.GetTrackerTable(TABLE_NAME2).IsEmpty(), true);
236         CloseStore();
237     }
238 
239     class DistributedDBInterfacesRelationalTrackerTableTest : public testing::Test {
240     public:
241         static void SetUpTestCase(void);
242 
243         static void TearDownTestCase(void);
244 
245         void SetUp();
246 
247         void TearDown();
248     };
249 
SetUpTestCase(void)250     void DistributedDBInterfacesRelationalTrackerTableTest::SetUpTestCase(void)
251     {
252         DistributedDBToolsUnitTest::TestDirInit(g_testDir);
253         LOGD("Test dir is %s", g_testDir.c_str());
254         g_dbDir = g_testDir + "/";
255         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
256     }
257 
TearDownTestCase(void)258     void DistributedDBInterfacesRelationalTrackerTableTest::TearDownTestCase(void)
259     {
260     }
261 
SetUp(void)262     void DistributedDBInterfacesRelationalTrackerTableTest::SetUp(void)
263     {
264         if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
265             LOGE("rm test db files error.");
266         }
267         DistributedDBToolsUnitTest::PrintTestCaseInfo();
268     }
269 
TearDown(void)270     void DistributedDBInterfacesRelationalTrackerTableTest::TearDown(void)
271     {
272         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
273     }
274 
SetTrackerTableTest(const TrackerSchema & schema,DBStatus expect)275 void SetTrackerTableTest(const TrackerSchema &schema, DBStatus expect)
276 {
277     CreateMultiTable();
278     OpenStore();
279     EXPECT_EQ(g_delegate->SetTrackerTable(schema), expect);
280     CloseStore();
281 }
282 
283 /**
284   * @tc.name: TrackerTableTest001
285   * @tc.desc: Test set tracker table with invalid table name
286   * @tc.type: FUNC
287   * @tc.require:
288   * @tc.author: bty
289   */
290 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest001, TestSize.Level0)
291 {
292     CreateMultiTable();
293     OpenStore();
294     /**
295      * @tc.steps:step1. table name is empty
296      * @tc.expected: step1. Return INVALID_ARGS.
297      */
298     TrackerSchema schema;
299     EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
300 
301     /**
302      * @tc.steps:step2. table name is no exist
303      * @tc.expected: step2. Return NOT_FOUND.
304      */
305     schema.tableName = "xx";
306     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
307 
308     /**
309      * @tc.steps:step3. table name is illegal table name
310      * @tc.expected: step3. Return INVALID_ARGS.
311      */
312     schema.tableName = DBConstant::SYSTEM_TABLE_PREFIX + "_1";
313     EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
314     CloseStore();
315 }
316 
317 /**
318   * @tc.name: TrackerTableTest002
319   * @tc.desc: Test set tracker table with empty colNames
320   * @tc.type: FUNC
321   * @tc.require:
322   * @tc.author: bty
323   */
324 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest002, TestSize.Level0)
325 {
326     /**
327      * @tc.steps:step1. trackerColNames is empty
328      * @tc.expected: step1. Return OK.
329      */
330     TrackerSchema schema;
331     schema.tableName = TABLE_NAME1;
332     SetTrackerTableTest(schema, OK);
333 
334     /**
335      * @tc.steps:step2. trackerColNames is empty but extendColName is no exist
336      * @tc.expected: step2. Return OK.
337      */
338     schema.extendColName = EXTEND_COL_NAME1;
339     SetTrackerTableTest(schema, OK);
340 
341     /**
342      * @tc.steps:step1. param valid but extend name is empty
343      * @tc.expected: step1. Return OK.
344      */
345     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
346     schema.extendColName = {};
347     SetTrackerTableTest(schema, OK);
348 }
349 
350 /**
351   * @tc.name: TrackerTableTest003
352   * @tc.desc: Test set tracker table with invalid col name
353   * @tc.type: FUNC
354   * @tc.require:
355   * @tc.author: bty
356   */
357 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest003, TestSize.Level0)
358 {
359     /**
360      * @tc.steps:step1. tracker col name is no exist
361      * @tc.expected: step1. Return SCHEMA_MISMATCH.
362      */
363     TrackerSchema schema;
364     schema.tableName = TABLE_NAME1;
365     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET1;
366     SetTrackerTableTest(schema, SCHEMA_MISMATCH);
367 
368     /**
369      * @tc.steps:step2. tracker col names contains empty name
370      * @tc.expected: step2. Return INVALID_ARGS.
371      */
372     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET5;
373     SetTrackerTableTest(schema, INVALID_ARGS);
374 
375     /**
376      * @tc.steps:step3. extend name is no exist
377      * @tc.expected: step3. Return SCHEMA_MISMATCH.
378      */
379     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
380     schema.extendColName = EXTEND_COL_NAME1;
381     SetTrackerTableTest(schema, SCHEMA_MISMATCH);
382 }
383 
384 /**
385   * @tc.name: TrackerTableTest005
386   * @tc.desc: Test set tracker table in same delegate
387   * @tc.type: FUNC
388   * @tc.require:
389   * @tc.author: bty
390   */
391 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest005, TestSize.Level0)
392 {
393     /**
394      * @tc.steps:step1. SetTrackerTable twice in same delegate
395      * @tc.expected: step1. Return WITH_INVENTORY_DATA for the first time, return OK again
396      */
397     TrackerSchema schema = g_normalSchema1;
398     CreateMultiTable();
399     OpenStore();
400     uint64_t num = 10;
401     BatchInsertTableName2Data(num);
402     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
403     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
404     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
405 
406     /**
407      * @tc.steps:step2. SetTrackerTable again with different schema
408      * @tc.expected: step2. Return OK.
409      */
410     schema = g_normalSchema3;
411     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
412     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
413     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
414 
415     /**
416      * @tc.steps:step3. SetTrackerTable again with different table
417      * @tc.expected: step3. Return OK.
418      */
419     schema.tableName = TABLE_NAME1;
420     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
421     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
422 
423     /**
424      * @tc.steps:step4. unSetTrackerTable
425      * @tc.expected: step4. Return OK.
426      */
427     schema.tableName = TABLE_NAME2;
428     schema.trackerColNames = {};
429     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
430     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
431     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
432     CloseStore();
433 }
434 
435 /**
436   * @tc.name: TrackerTableTest006
437   * @tc.desc: Test set tracker table in diff delegate
438   * @tc.type: FUNC
439   * @tc.require:
440   * @tc.author: bty
441   */
442 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest006, TestSize.Level0)
443 {
444     /**
445      * @tc.steps:step1. SetTrackerTable
446      * @tc.expected: step1. Return OK.
447      */
448     TrackerSchema schema = g_normalSchema1;
449     CreateMultiTable();
450     OpenStore();
451     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
452     uint64_t num = 10;
453     BatchInsertTableName2Data(num);
454     CloseStore();
455 
456     /**
457      * @tc.steps:step2. reopen db and SetTrackerTable
458      * @tc.expected: step2. Return OK.
459      */
460     OpenStore();
461     schema = g_normalSchema2;
462     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
463     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
464     CloseStore();
465 
466     /**
467      * @tc.steps:step3. reopen db and SetTrackerTable with diff table
468      * @tc.expected: step3. Return OK.
469      */
470     OpenStore();
471     schema.tableName = TABLE_NAME1;
472     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
473     CloseStore();
474 
475     /**
476      * @tc.steps:step4. reopen db and unSetTrackerTable
477      * @tc.expected: step4. Return OK.
478      */
479     OpenStore();
480     schema.trackerColNames = {};
481     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
482     CloseStore();
483 }
484 
485 /**
486   * @tc.name: TrackerTableTest007
487   * @tc.desc: Test set tracker table to upgrade inventory data
488   * @tc.type: FUNC
489   * @tc.require:
490   * @tc.author: bty
491   */
492 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest007, TestSize.Level0)
493 {
494     /**
495      * @tc.steps:step1. SetTrackerTable when the db exist data
496      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
497      */
498     uint64_t num = 10;
499     CreateMultiTable();
500     BatchInsertTableName2Data(num);
501     OpenStore();
502     TrackerSchema schema = g_normalSchema3;
503     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
504 
505     /**
506      * @tc.steps:step2. SetTrackerTable again with diff tracker schema
507      * @tc.expected: step2. Return OK.
508      */
509     schema = g_normalSchema1;
510     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
511 
512     /**
513      * @tc.steps:step3. check extend_field and cursor
514      * @tc.expected: step3. Return OK.
515      */
516     CheckExtendAndCursor(num, 0);
517 
518     /**
519      * @tc.steps:step4. update extend field and check
520      * @tc.expected: step4. Return OK.
521      */
522     EXPECT_EQ(g_delegate->SetTrackerTable(g_normalSchema3), OK);
523     std::string sql = "UPDATE " + TABLE_NAME2 + " SET age='666'";
524     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
525     sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
526         " where extend_field=666;";
527     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
528         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
529     CloseStore();
530 }
531 
532 /**
533   * @tc.name: TrackerTableTest008
534   * @tc.desc: Test set tracker table to check extend_field and cursor
535   * @tc.type: FUNC
536   * @tc.require:
537   * @tc.author: bty
538   */
539 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest008, TestSize.Level0)
540 {
541     /**
542      * @tc.steps:step1. SetTrackerTable on table2
543      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
544      */
545     uint64_t num = 10;
546     CreateMultiTable();
547     BatchInsertTableName2Data(num);
548     OpenStore();
549     TrackerSchema schema = g_normalSchema1;
550     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
551 
552     /**
553      * @tc.steps:step2. Update non tracker columns,then check extend_field and cursor
554      * @tc.expected: step2. Return OK.
555      */
556     uint64_t updateNum = 2;
557     BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET3);
558     int index = 0;
559     string querySql = "select extend_field, cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
560         " where data_key <= " + std::to_string(updateNum);
561     sqlite3_stmt *stmt = nullptr;
562     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
563     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
564         std::string extendVal;
565         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
566         EXPECT_EQ(extendVal, "Local" + std::to_string(index % num));
567         std::string cursorVal;
568         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
569         EXPECT_EQ(cursorVal, std::to_string(++index));
570     }
571     int errCode;
572     SQLiteUtils::ResetStatement(stmt, true, errCode);
573 
574     /**
575      * @tc.steps:step3. Update tracker columns,then check extend_field and cursor
576      * @tc.expected: step3. Return OK.
577      */
578     BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET2);
579     stmt = nullptr;
580     index = 0;
581     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
582     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
583         std::string extendVal;
584         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
585         EXPECT_EQ(extendVal, "1");
586         std::string cursorVal;
587         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
588         EXPECT_EQ(cursorVal, std::to_string(num + (++index)));
589     }
590     SQLiteUtils::ResetStatement(stmt, true, errCode);
591     CloseStore();
592 }
593 
594 /**
595   * @tc.name: TrackerTableTest009
596   * @tc.desc: Test set tracker table to check extend_field and cursor after delete
597   * @tc.type: FUNC
598   * @tc.require:
599   * @tc.author: bty
600   */
601 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest009, TestSize.Level0)
602 {
603     /**
604      * @tc.steps:step1. SetTrackerTable on table2
605      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
606      */
607     uint64_t num = 10;
608     CreateMultiTable();
609     BatchInsertTableName2Data(num);
610     OpenStore();
611     TrackerSchema schema = g_normalSchema1;
612     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
613 
614     /**
615      * @tc.steps:step2. select extend_field and cursor after delete
616      * @tc.expected: step2. Return OK.
617      */
618     BatchDeleteTableName2Data(num);
619     CheckExtendAndCursor(num, 0);
620     CloseStore();
621 }
622 
623 /**
624   * @tc.name: TrackerTableTest010
625   * @tc.desc: Test set tracker table after unSetTrackerTable
626   * @tc.type: FUNC
627   * @tc.require:
628   * @tc.author: bty
629   */
630 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest010, TestSize.Level0)
631 {
632     /**
633      * @tc.steps:step1. SetTrackerTable on table2
634      * @tc.expected: step1. Return OK.
635      */
636     CreateMultiTable();
637     OpenStore();
638     TrackerSchema schema = g_normalSchema1;
639     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
640 
641     /**
642      * @tc.steps:step2. unSetTrackerTable
643      * @tc.expected: step2. Return OK.
644      */
645     schema.trackerColNames = {};
646     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
647 
648     /**
649      * @tc.steps:step3. SetTrackerTable again
650      * @tc.expected: step3. Return OK.
651      */
652     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
653     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
654 
655     /**
656      * @tc.steps:step4. operator data
657      * @tc.expected: step4. Return OK.
658      */
659     uint64_t num = 10;
660     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
661     CloseStore();
662 }
663 
664 /**
665   * @tc.name: TrackerTableTest011
666   * @tc.desc: Test CreateDistributedTable after set tracker table
667   * @tc.type: FUNC
668   * @tc.require:
669   * @tc.author: bty
670   */
671 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest011, TestSize.Level0)
672 {
673     /**
674      * @tc.steps:step1. SetTrackerTable on table2
675      * @tc.expected: step1. Return OK.
676      */
677     CreateMultiTable();
678     OpenStore();
679     TrackerSchema schema = g_normalSchema1;
680     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
681 
682     /**
683      * @tc.steps:step2. CreateDistributedTable on table2 and insert data
684      * @tc.expected: step2. Return OK.
685      */
686     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
687     uint64_t num = 10;
688     BatchInsertTableName2Data(num);
689 
690     /**
691      * @tc.steps:step3. CreateDistributedTable on table2 again, but schema not change
692      * @tc.expected: step3. Return OK.
693      */
694     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
695     CheckExtendAndCursor(num, -num);
696 
697     /**
698      * @tc.steps:step4. operator data on table2
699      * @tc.expected: step4. Return OK.
700      */
701     std::string sql = "ALTER TABLE " + TABLE_NAME2 + " ADD COLUMN xxx INT";
702     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
703     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
704     CheckExtendAndCursor(num, 0);
705 
706     /**
707      * @tc.steps:step5. unSetTrackerTable
708      * @tc.expected: step5. Return OK.
709      */
710     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
711     schema.trackerColNames = {};
712     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
713 
714     /**
715      * @tc.steps:step6. operator data on table2
716      * @tc.expected: step6. Return OK.
717      */
718     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
719     CloseStore();
720 }
721 
722 /**
723   * @tc.name: TrackerTableTest012
724   * @tc.desc: Test CreateDistributedTable after set tracker table
725   * @tc.type: FUNC
726   * @tc.require:
727   * @tc.author: bty
728   */
729 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest012, TestSize.Level0)
730 {
731     /**
732      * @tc.steps:step1. SetTrackerTable on table2
733      * @tc.expected: step1. Return OK.
734      */
735     CreateMultiTable();
736     OpenStore();
737     TrackerSchema schema = g_normalSchema1;
738     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
739 
740     /**
741      * @tc.steps:step2. CreateDistributedTable on table2 without data
742      * @tc.expected: step2. Return OK.
743      */
744     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
745 
746     /**
747      * @tc.steps:step3. CreateDistributedTable on table1
748      * @tc.expected: step3. Return OK.
749      */
750     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME1, CLOUD_COOPERATION), DBStatus::OK);
751 
752     /**
753      * @tc.steps:step4. operator data on table2
754      * @tc.expected: step4. Return OK.
755      */
756     uint64_t num = 10;
757     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
758 
759     /**
760      * @tc.steps:step5. unSetTrackerTable
761      * @tc.expected: step5. Return OK.
762      */
763     schema.trackerColNames = {};
764     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
765 
766     /**
767      * @tc.steps:step6. operator data on table2
768      * @tc.expected: step6. Return OK.
769      */
770     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
771     CloseStore();
772 }
773 
774 /**
775   * @tc.name: TrackerTableTest013
776   * @tc.desc: Test CreateDistributedTable after clean table data
777   * @tc.type: FUNC
778   * @tc.require:
779   * @tc.author: bty
780   */
781 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest013, TestSize.Level0)
782 {
783     /**
784      * @tc.steps:step1. init data and SetTrackerTable on table2
785      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
786      */
787     uint64_t num = 10;
788     CreateMultiTable();
789     BatchInsertTableName2Data(num);
790     OpenStore();
791     TrackerSchema schema = g_normalSchema1;
792     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
793 
794     /**
795      * @tc.steps:step2. CreateDistributedTable on table2
796      * @tc.expected: step2. Return NOT_SUPPORT.
797      */
798     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
799 
800     /**
801      * @tc.steps:step3. delete all data but keep the log , then CreateDistributedTable
802      * @tc.expected: step3. Return OK.
803      */
804     BatchDeleteTableName2Data(num);
805     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
806     BatchInsertTableName2Data(num);
807     CloseStore();
808 }
809 
810 /**
811   * @tc.name: TrackerTableTest014
812   * @tc.desc: Test SetTrackerTable after CreateDistributedTable
813   * @tc.type: FUNC
814   * @tc.require:
815   * @tc.author: bty
816   */
817 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest014, TestSize.Level0)
818 {
819     /**
820      * @tc.steps:step1. CreateDistributedTable on table2
821      * @tc.expected: step1. Return OK.
822      */
823     CreateMultiTable();
824     OpenStore();
825     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
826 
827     /**
828      * @tc.steps:step2. SetTrackerTable on table2
829      * @tc.expected: step2. Return OK.
830      */
831     TrackerSchema schema = g_normalSchema1;
832     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
833 
834     /**
835      * @tc.steps:step3. operator data and check extend_filed and cursor
836      * @tc.expected: step3. Return OK.
837      */
838     uint64_t num = 10;
839     int begin = -10;
840     BatchInsertTableName2Data(num);
841     CheckExtendAndCursor(num, begin);
842     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
843 
844     /**
845      * @tc.steps:step4. unSetTrackerTable
846      * @tc.expected: step4. Return OK.
847      */
848     schema.trackerColNames = {};
849     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
850     CloseStore();
851 }
852 
853 /**
854   * @tc.name: TrackerTableTest015
855   * @tc.desc: Test operator data on Distributed tracker table
856   * @tc.type: FUNC
857   * @tc.require:
858   * @tc.author: bty
859   */
860 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest015, TestSize.Level0)
861 {
862     /**
863      * @tc.steps:step1. CreateDistributedTable on table2
864      * @tc.expected: step1. Return OK.
865      */
866     CreateMultiTable();
867     OpenStore();
868     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
869 
870     /**
871      * @tc.steps:step2. operator data
872      * @tc.expected: step2. Return OK.
873      */
874     uint64_t num = 10;
875     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
876 
877     /**
878      * @tc.steps:step3. SetTrackerTable on table2
879      * @tc.expected: step3. Return WITH_INVENTORY_DATA.
880      */
881     TrackerSchema schema = g_normalSchema1;
882     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
883     string querySql = "select extend_field from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
884         " where data_key = 15;";
885     sqlite3_stmt *stmt = nullptr;
886     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
887     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
888         std::string extendVal;
889         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
890         EXPECT_EQ(extendVal, "Local4");
891     }
892     int errCode;
893     SQLiteUtils::ResetStatement(stmt, true, errCode);
894 
895     /**
896      * @tc.steps:step4. operator data
897      * @tc.expected: step4. Return OK.
898      */
899     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
900     CloseStore();
901 }
902 
903 /**
904   * @tc.name: TrackerTableTest016
905   * @tc.desc: Test operator data on tracker Distributed table
906   * @tc.type: FUNC
907   * @tc.require:
908   * @tc.author: bty
909   */
910 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest016, TestSize.Level0)
911 {
912     /**
913      * @tc.steps:step1. SetTrackerTable on table2
914      * @tc.expected: step1. Return OK.
915      */
916     CreateMultiTable();
917     OpenStore();
918     TrackerSchema schema = g_normalSchema1;
919     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
920 
921     /**
922      * @tc.steps:step2. reopen store and create distributed table
923      * @tc.expected: step2. Return OK.
924      */
925     CloseStore();
926     OpenStore();
927     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
928 
929     /**
930      * @tc.steps:step3. operator data
931      * @tc.expected: step3. Return OK.
932      */
933     uint64_t num = 10;
934     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
935     CloseStore();
936 }
937 
938 /**
939   * @tc.name: TrackerTableTest017
940   * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
941   * @tc.type: FUNC
942   * @tc.require:
943   * @tc.author: bty
944   */
945 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest017, TestSize.Level0)
946 {
947     /**
948      * @tc.steps:step1. SetTrackerTable on table2
949      * @tc.expected: step1. Return OK.
950      */
951     CreateMultiTable();
952     OpenStore();
953     TrackerSchema schema = g_normalSchema1;
954     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
955 
956     /**
957      * @tc.steps:step2. Create DEVICE_COOPERATION DistributedTable
958      * @tc.expected: step2. Return NOT_SUPPORT.
959      */
960     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::NOT_SUPPORT);
961 
962     /**
963      * @tc.steps:step3. operator data on table2
964      * @tc.expected: step3. Return OK.
965      */
966     uint64_t num = 10;
967     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
968 
969     /**
970      * @tc.steps:step4. unSetTrackerTable
971      * @tc.expected: step4. Return OK.
972      */
973     schema.trackerColNames = {};
974     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
975 
976     /**
977      * @tc.steps:step5. There is still data in the table
978      * @tc.expected: step5. Return NOT_SUPPORT.
979      */
980     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), OK);
981 
982     /**
983      * @tc.steps:step6. clear all data and create DEVICE_COOPERATION table
984      * @tc.expected: step6. Return OK.
985      */
986     BatchDeleteTableName2Data(num + num);
987     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), OK);
988 
989     /**
990      * @tc.steps:step7. operator data on table2
991      * @tc.expected: step7. Return OK.
992      */
993     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
994     CloseStore();
995 }
996 
997 /**
998   * @tc.name: TrackerTableTest018
999   * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
1000   * @tc.type: FUNC
1001   * @tc.require:
1002   * @tc.author: bty
1003   */
1004 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest018, TestSize.Level0)
1005 {
1006     /**
1007      * @tc.steps:step1. Create DEVICE_COOPERATION DistributedTable
1008      * @tc.expected: step1. Return OK.
1009      */
1010     CreateMultiTable();
1011     OpenStore();
1012     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
1013 
1014     /**
1015      * @tc.steps:step2. SetTrackerTable on table2
1016      * @tc.expected: step2. Return NOT_SUPPORT.
1017      */
1018     TrackerSchema schema = g_normalSchema1;
1019     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_SUPPORT);
1020 
1021     /**
1022      * @tc.steps:step3. operator data on table2
1023      * @tc.expected: step3. Return OK.
1024      */
1025     uint64_t num = 10;
1026     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1027 
1028     /**
1029      * @tc.steps:step4. unSetTrackerTable
1030      * @tc.expected: step4. Return NOT_SUPPORT.
1031      */
1032     schema.trackerColNames = {};
1033     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_SUPPORT);
1034 
1035     /**
1036      * @tc.steps:step5. operator data on table2
1037      * @tc.expected: step5. Return OK.
1038      */
1039     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1040     CloseStore();
1041 }
1042 
1043 /**
1044   * @tc.name: TrackerTableTest019
1045   * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
1046   * @tc.type: FUNC
1047   * @tc.require:
1048   * @tc.author: bty
1049   */
1050 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest019, TestSize.Level0)
1051 {
1052     /**
1053      * @tc.steps:step1. SetTrackerTable
1054      * @tc.expected: step1. Return OK.
1055      */
1056     CreateMultiTable();
1057     OpenStore();
1058     TrackerSchema schema = g_normalSchema1;
1059     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1060 
1061     /**
1062      * @tc.steps:step2. CleanTrackerData with table name no exist
1063      * @tc.expected: step2. Return DB_ERROR.
1064      */
1065     uint64_t num = 10;
1066     BatchInsertTableName2Data(num);
1067     BatchDeleteTableName2Data(num / HALF);
1068     EXPECT_EQ(g_delegate->CleanTrackerData("xx", num), DB_ERROR);
1069 
1070     /**
1071      * @tc.steps:step3. CleanTrackerData with empty table name
1072      * @tc.expected: step3. Return INVALID_ARGS.
1073      */
1074     EXPECT_EQ(g_delegate->CleanTrackerData("", num), INVALID_ARGS);
1075 
1076     /**
1077      * @tc.steps:step4. CleanTrackerData
1078      * @tc.expected: step4. Return OK.
1079      */
1080     EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK);
1081     std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
1082         " where extend_field is NULL;";
1083     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1084         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1085     CloseStore();
1086 }
1087 
1088 /**
1089   * @tc.name: TrackerTableTest020
1090   * @tc.desc: Test drop and rebuild table in same delegate
1091   * @tc.type: FUNC
1092   * @tc.require:
1093   * @tc.author: bty
1094   */
1095 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest020, TestSize.Level0)
1096 {
1097     /**
1098      * @tc.steps:step1. SetTrackerTable and init data
1099      * @tc.expected: step1. Return OK.
1100      */
1101     CreateMultiTable();
1102     OpenStore();
1103     TrackerSchema schema = g_normalSchema1;
1104     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1105     uint64_t num = 10;
1106     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1107 
1108     /**
1109      * @tc.steps:step2. drop and rebuild table, then SetTrackerTable
1110      * @tc.expected: step2. Return OK.
1111      */
1112     std::string sql = "drop table if exists " + TABLE_NAME2;
1113     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1114     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
1115     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1116 
1117     /**
1118      * @tc.steps:step3. check the extend_field and cursor is null
1119      * @tc.expected: step3. Return OK.
1120      */
1121     sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log where extend_field is NULL " +
1122         " AND cursor is NULL";
1123     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1124         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1125 
1126     /**
1127      * @tc.steps:step4. set diff schema, check the extend_field and cursor is null
1128      * @tc.expected: step4. Return OK.
1129      */
1130     schema.extendColName = EXTEND_COL_NAME3;
1131     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1132     sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log where extend_field is NULL " +
1133         " AND cursor is NULL";
1134     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1135         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1136     CloseStore();
1137 }
1138 
1139 /**
1140   * @tc.name: TrackerTableTest021
1141   * @tc.desc: Test non distributed table delete table and reopen db
1142   * @tc.type: FUNC
1143   * @tc.require:
1144   * @tc.author: bty
1145   */
1146 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest021, TestSize.Level0)
1147 {
1148     CheckDropTableAndReopenDb(false);
1149 }
1150 
1151 /**
1152   * @tc.name: TrackerTableTest022
1153   * @tc.desc: Test distributed table delete table and reopen db
1154   * @tc.type: FUNC
1155   * @tc.require:
1156   * @tc.author: bty
1157   */
1158 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest022, TestSize.Level0)
1159 {
1160     CheckDropTableAndReopenDb(true);
1161 }
1162 
1163 /**
1164   * @tc.name: TrackerTableTest023
1165   * @tc.desc: Test drop and rebuild table,then insert data and set tracker table
1166   * @tc.type: FUNC
1167   * @tc.require:
1168   * @tc.author: bty
1169   */
1170 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest023, TestSize.Level0)
1171 {
1172     /**
1173      * @tc.steps:step1. SetTrackerTable and init data
1174      * @tc.expected: step1. Return OK.
1175      */
1176     CreateMultiTable();
1177     OpenStore();
1178     TrackerSchema schema = g_normalSchema1;
1179     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1180     uint64_t num = 10;
1181     BatchInsertTableName2Data(num);
1182     BatchDeleteTableName2Data(num);
1183 
1184     /**
1185      * @tc.steps:step2. drop and rebuild table,then insert data and set tracker table
1186      * @tc.expected: step2. Return OK.
1187      */
1188     std::string sql = "drop table if exists " + TABLE_NAME2;
1189     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1190     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
1191     BatchInsertTableName2Data(num);
1192     schema = g_normalSchema2;
1193     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1194 
1195     /**
1196      * @tc.steps:step3. query cursor
1197      * @tc.expected: step3. Return OK.
1198      */
1199     string querySql = "select cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log";
1200     sqlite3_stmt *stmt = nullptr;
1201     int index = 20;
1202     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
1203     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1204         std::string cursorVal;
1205         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, cursorVal), E_OK);
1206         EXPECT_EQ(cursorVal, std::to_string(++index));
1207     }
1208     int errCode;
1209     SQLiteUtils::ResetStatement(stmt, true, errCode);
1210     CloseStore();
1211 }
1212 
1213 /**
1214   * @tc.name: TrackerTableTest024
1215   * @tc.desc: Test set tracker table and set extend col as the asset type
1216   * @tc.type: FUNC
1217   * @tc.require:
1218   * @tc.author: bty
1219   */
1220 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest024, TestSize.Level0)
1221 {
1222     CreateMultiTable();
1223     OpenStore();
1224     TrackerSchema schema;
1225     schema.tableName = TABLE_NAME3;
1226     schema.extendColName = EXTEND_COL_NAME3;
1227     schema.trackerColNames = { EXTEND_COL_NAME3 };
1228     EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
1229     CloseStore();
1230 }
1231 
1232 /**
1233   * @tc.name: ExecuteSql001
1234   * @tc.desc: Test ExecuteSql with invalid param
1235   * @tc.type: FUNC
1236   * @tc.require:
1237   * @tc.author: bty
1238   */
1239 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql001, TestSize.Level0)
1240 {
1241     /**
1242      * @tc.steps:step1. init db data
1243      * @tc.expected: step1. Return OK.
1244      */
1245     uint64_t num = 10;
1246     CreateMultiTable();
1247     BatchInsertTableName2Data(num);
1248     OpenStore();
1249 
1250     /**
1251      * @tc.steps:step2. sql is empty
1252      * @tc.expected: step2. Return INVALID_ARGS.
1253      */
1254     SqlCondition condition;
1255     std::vector<VBucket> records;
1256     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1257 
1258     /**
1259      * @tc.steps:step3. SQL does not have placeholders but there are bind args present
1260      * @tc.expected: step3. Return INVALID_ARGS.
1261      */
1262     std::string querySql = "select * from " + TABLE_NAME2 + " where id = 1;";
1263     condition.sql = querySql;
1264     condition.bindArgs = {"1"};
1265     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1266 
1267     /**
1268      * @tc.steps:step4. More SQL binding parameters than SQL placeholders
1269      * @tc.expected: step4. Return INVALID_ARGS.
1270      */
1271     querySql = "select * from " + TABLE_NAME2 + " where id > ?;";
1272     condition.sql = querySql;
1273     condition.bindArgs = {};
1274     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1275 
1276     /**
1277      * @tc.steps:step5. More SQL placeholders than SQL binding parameters
1278      * @tc.expected: step5. Return INVALID_ARGS.
1279      */
1280     condition.bindArgs = {"1", "2"};
1281     condition.sql = querySql;
1282     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1283     CloseStore();
1284 }
1285 
1286 /**
1287   * @tc.name: ExecuteSql002
1288   * @tc.desc: Test ExecuteSql and check query result
1289   * @tc.type: FUNC
1290   * @tc.require:
1291   * @tc.author: bty
1292   */
1293 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql002, TestSize.Level0)
1294 {
1295     /**
1296      * @tc.steps:step1. init db data
1297      * @tc.expected: step1. Return OK.
1298      */
1299     uint64_t num = 10;
1300     CreateMultiTable();
1301     BatchInsertTableName2Data(num);
1302     OpenStore();
1303 
1304     /**
1305      * @tc.steps:step2. execute query sql and check result
1306      * @tc.expected: step2. Return OK.
1307      */
1308     int64_t beginId = 1;
1309     SqlCondition condition;
1310     std::vector<VBucket> records;
1311     std::string querySql = "select * from " + TABLE_NAME2 + " where id > ?;";
1312     condition.sql = querySql;
1313     condition.bindArgs = {beginId};
1314     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1315     EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1316     for (const VBucket &item: records) {
1317         auto iter = item.find("id");
1318         ASSERT_NE(iter, item.end());
1319         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<int64_t>);
1320         EXPECT_EQ(std::get<int64_t>(iter->second), beginId + 1);
1321 
1322         iter = item.find("name");
1323         ASSERT_NE(iter, item.end());
1324         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<std::string>);
1325         EXPECT_EQ(std::get<std::string>(iter->second), "Local" + std::to_string(beginId));
1326 
1327         iter = item.find("height");
1328         ASSERT_NE(iter, item.end());
1329         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<double>);
1330         EXPECT_EQ(std::get<double>(iter->second), 175.8);
1331 
1332         iter = item.find("photo");
1333         ASSERT_NE(iter, item.end());
1334         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<double>);
1335         EXPECT_EQ(std::get<double>(iter->second), 175.88888888888);
1336 
1337         iter = item.find("asserts");
1338         ASSERT_NE(iter, item.end());
1339         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<std::string>);
1340         EXPECT_EQ(std::get<std::string>(iter->second), "x");
1341         beginId++;
1342     }
1343     CloseStore();
1344 }
1345 
1346 /**
1347   * @tc.name: ExecuteSql003
1348   * @tc.desc: Test ExecuteSql and check update and delete result
1349   * @tc.type: FUNC
1350   * @tc.require:
1351   * @tc.author: bty
1352   */
1353 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql003, TestSize.Level0)
1354 {
1355     /**
1356      * @tc.steps:step1. init db data
1357      * @tc.expected: step1. Return OK.
1358      */
1359     uint64_t num = 10;
1360     CreateMultiTable();
1361     BatchInsertTableName2Data(num);
1362     OpenStore();
1363 
1364     /**
1365      * @tc.steps:step2. update sql
1366      * @tc.expected: step2. Return OK.
1367      */
1368     int64_t beginId = 1;
1369     SqlCondition condition;
1370     std::vector<VBucket> records;
1371     std::string updateSql = "update " + TABLE_NAME2 + " set age = 3 where id = ?;";
1372     condition.sql = updateSql;
1373     condition.bindArgs = {beginId};
1374     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1375     EXPECT_EQ(records.size(), 0u);
1376 
1377     std::string delSql = "delete from " + TABLE_NAME2 + " where id = ?;";
1378     condition.sql = delSql;
1379     condition.bindArgs = {beginId + 1};
1380     std::vector<VBucket> records2;
1381     EXPECT_EQ(g_delegate->ExecuteSql(condition, records2), OK);
1382     EXPECT_EQ(records2.size(), 0u);
1383 
1384     string insSql = "INSERT INTO " + TABLE_NAME2 +
1385         " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(num + 1) +
1386         "', '175.8', '0', 'x', ?);";
1387     condition.sql = insSql;
1388     condition.bindArgs = {beginId};
1389     std::vector<VBucket> records3;
1390     EXPECT_EQ(g_delegate->ExecuteSql(condition, records3), OK);
1391     EXPECT_EQ(records3.size(), 0u);
1392     CloseStore();
1393 }
1394 
1395 /**
1396   * @tc.name: ExecuteSql004
1397   * @tc.desc: Test ExecuteSql after SetTrackerTable
1398   * @tc.type: FUNC
1399   * @tc.require:
1400   * @tc.author: bty
1401   */
1402 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql004, TestSize.Level0)
1403 {
1404     /**
1405      * @tc.steps:step1. SetTrackerTable
1406      * @tc.expected: step1. Return OK.
1407      */
1408     CreateMultiTable();
1409     OpenStore();
1410     TrackerSchema schema = g_normalSchema1;
1411     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1412 
1413     /**
1414      * @tc.steps:step2. batch insert
1415      * @tc.expected: step2. Return OK.
1416      */
1417     uint64_t num = 10;
1418     BatchInsertTableName2Data(num);
1419 
1420     /**
1421      * @tc.steps:step3. execute query sql and check result
1422      * @tc.expected: step3. Return OK.
1423      */
1424     int64_t begin = 0;
1425     SqlCondition condition;
1426     std::vector<VBucket> records;
1427     std::string querySql = "select " + TABLE_NAME2 + ".* from " + TABLE_NAME2 + " join ";
1428     querySql += DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + " as a on " + TABLE_NAME2 + "._rowid_ = ";
1429     querySql += "a.data_key where a.cursor > ?;";
1430     condition.sql = querySql;
1431     condition.bindArgs = {begin};
1432     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1433     EXPECT_EQ(records.size(), num);
1434 
1435     /**
1436      * @tc.steps:step4. update
1437      * @tc.expected: step4. Return OK.
1438      */
1439     std::string updateSql = "update " + TABLE_NAME2 + " set name = '3' where _rowid_ <= 5;";
1440     condition.sql = updateSql;
1441     condition.bindArgs = {};
1442     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1443 
1444     /**
1445      * @tc.steps:step5. query after updating
1446      * @tc.expected: step5. Return OK.
1447      */
1448     records.clear();
1449     begin = 10;
1450     condition.sql = querySql;
1451     condition.bindArgs = {begin};
1452     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1453     EXPECT_EQ(records.size(), 5u); // 5 is the num of update
1454     CloseStore();
1455 }
1456 
1457 /**
1458   * @tc.name: ExecuteSql005
1459   * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1460   * @tc.type: FUNC
1461   * @tc.require:
1462   * @tc.author: bty
1463   */
1464 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql005, TestSize.Level0)
1465 {
1466     /**
1467      * @tc.steps:step1. init db data
1468      * @tc.expected: step1. Return OK.
1469      */
1470     uint64_t num = 10;
1471     CreateMultiTable();
1472     BatchInsertTableName2Data(num);
1473     OpenStore();
1474 
1475     /**
1476      * @tc.steps:step2. execute query sql but the table is no exist
1477      * @tc.expected: step2. Return DB_ERROR.
1478      */
1479     int64_t beginId = 1;
1480     SqlCondition condition;
1481     std::vector<VBucket> records;
1482     std::string querySql = "select * from " + TABLE_NAME2 + " where id > 1;";
1483     querySql += "select _rowid_ from " + TABLE_NAME2 + " where id = 1;";
1484     condition.sql = querySql;
1485     condition.bindArgs = {};
1486     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1487     EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1488 
1489     /**
1490      * @tc.steps:step3. execute multi query sql and the num of bindArgs is greater than the first sql
1491      * @tc.expected: step3. Return INVALID_ARGS.
1492      */
1493     records = {};
1494     std::string querySql2 = "select * from " + TABLE_NAME2 + " where id > ?;";
1495     querySql2 += "select _rowid_ from " + TABLE_NAME2 + " where id = ?;";
1496     condition.sql = querySql2;
1497     condition.bindArgs = {beginId, beginId};
1498     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1499     EXPECT_EQ(records.size(), 0u);
1500 
1501     /**
1502      * @tc.steps:step4. execute multi query sql and the num of bindArgs is equal to the first sql
1503      * @tc.expected: step4. Return OK.
1504      */
1505     records = {};
1506     condition.bindArgs = {beginId};
1507     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1508     EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1509     CloseStore();
1510 }
1511 
1512 /**
1513   * @tc.name: ExecuteSql006
1514   * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1515   * @tc.type: FUNC
1516   * @tc.require:
1517   * @tc.author: bty
1518   */
1519 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql006, TestSize.Level0)
1520 {
1521     /**
1522      * @tc.steps:step1. init db data
1523      * @tc.expected: step1. Return OK.
1524      */
1525     uint64_t num = 10;
1526     CreateMultiTable();
1527     BatchInsertTableName2Data(num);
1528     OpenStore();
1529 
1530     /**
1531      * @tc.steps:step2. execute multi update sql
1532      * @tc.expected: step2. Return OK.
1533      */
1534     SqlCondition condition;
1535     std::vector<VBucket> records;
1536     std::string updateSql = "update " + TABLE_NAME2 + " SET age = 100; ";
1537     updateSql += "update " + TABLE_NAME2 + " SET age = 50;";
1538     condition.sql = updateSql;
1539     condition.bindArgs = {};
1540     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1541 
1542     /**
1543      * @tc.steps:step3. execute query sql where age is 100
1544      * @tc.expected: step3. Return OK.
1545      */
1546     records = {};
1547     std::string querySql = "select * from " + TABLE_NAME2 + " where age = 100;";
1548     condition.sql = querySql;
1549     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1550     EXPECT_EQ(records.size(), num);
1551 
1552     /**
1553      * @tc.steps:step4. execute update sql and query sql
1554      * @tc.expected: step4. Return OK.
1555      */
1556     updateSql = "update " + TABLE_NAME2 + " SET age = 88; ";
1557     updateSql += "select * from " + TABLE_NAME2;
1558     condition.sql = updateSql;
1559     condition.bindArgs = {};
1560     records = {};
1561     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1562     EXPECT_EQ(records.size(), 0u);
1563 
1564     /**
1565      * @tc.steps:step5. execute multi delete sql
1566      * @tc.expected: step5. Return OK.
1567      */
1568     records = {};
1569     std::string delSql = "DELETE FROM " + TABLE_NAME2 + " WHERE age = 100; ";
1570     delSql += "DELETE FROM " + TABLE_NAME2 + " WHERE age = 88;";
1571     condition.sql = delSql;
1572     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1573 
1574     /**
1575      * @tc.steps:step6. execute query sql where age is 100
1576      * @tc.expected: step6. Return OK.
1577      */
1578     records = {};
1579     condition.sql = "select * from " + TABLE_NAME2 + " where age = 88;";
1580     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1581     EXPECT_EQ(records.size(), num);
1582     CloseStore();
1583 }
1584 
1585 /**
1586   * @tc.name: ExecuteSql006
1587   * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1588   * @tc.type: FUNC
1589   * @tc.require:
1590   * @tc.author: bty
1591   */
1592 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql007, TestSize.Level0)
1593 {
1594     /**
1595      * @tc.steps:step1. init db data
1596      * @tc.expected: step1. Return OK.
1597      */
1598     uint64_t num = 10;
1599     CreateMultiTable();
1600     BatchInsertTableName2Data(num);
1601     OpenStore();
1602 
1603     /**
1604      * @tc.steps:step2. ExecuteSql with transaction
1605      * @tc.expected: step2. Return OK.
1606      */
1607     SqlCondition condition;
1608     std::vector<VBucket> records;
1609     condition.sql = "BEGIN";
1610     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1611     condition.sql = "COMMIT;";
1612     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1613     condition.sql = "BEGIN";
1614     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1615     condition.sql = "ROLLBACK;";
1616     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1617     condition.sql = "BEGIN TRANSACTION;";
1618     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1619     condition.sql = "END TRANSACTION;";
1620     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1621     condition.sql = "BEGIN IMMEDIATE TRANSACTION;";
1622     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1623     condition.sql = "COMMIT;";
1624     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1625 
1626     /**
1627      * @tc.steps:step3. ExecuteSql with attach and detach
1628      * @tc.expected: step3. Return OK.
1629      */
1630     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID2 + DB_SUFFIX);
1631     EXPECT_NE(db, nullptr);
1632     condition.sql = "ATTACH DATABASE '" + g_dbDir + STORE_ID2 + DB_SUFFIX + "' AS TEST";
1633     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1634     condition.sql = "DETACH DATABASE TEST";
1635     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1636     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1637     db = nullptr;
1638     CloseStore();
1639 }
1640 
1641 /**
1642   * @tc.name: ExecuteSql008
1643   * @tc.desc: Test the ExecSql interface for bool type results
1644   * @tc.type: FUNC
1645   * @tc.require:
1646   * @tc.author: bty
1647   */
1648 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql008, TestSize.Level0)
1649 {
1650     /**
1651      * @tc.steps:step1. init db data
1652      * @tc.expected: step1. Return OK.
1653      */
1654     CreateMultiTable();
1655     OpenStore();
1656     uint64_t num = 10;
1657     for (size_t i = 0; i < num; i++) {
1658         string sql = "INSERT OR REPLACE INTO " + TABLE_NAME1 +
1659             " (name, height, married, photo, assert, age) VALUES ('Tom" + std::to_string(i) +
1660             "', '175.8', '0', '', '' , '18');";
1661         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1662     }
1663 
1664     /**
1665      * @tc.steps:step2. check if the result is of bool type
1666      * @tc.expected: step2. Return OK.
1667      */
1668     SqlCondition condition;
1669     condition.sql = "select * from " + TABLE_NAME1;
1670     std::vector<VBucket> records;
1671     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1672     EXPECT_EQ(records.size(), num);
1673     EXPECT_NE(records[0].find("married"), records[0].end());
1674     if (records[0].find("married") != records[0].end()) {
1675         Type married = records[0].find("married")->second;
1676         EXPECT_TRUE(married.index() == TYPE_INDEX<bool>);
1677     }
1678     CloseStore();
1679 }
1680 
1681 /**
1682   * @tc.name: ExecuteSql010
1683   * @tc.desc: Test ExecuteSql with temp table
1684   * @tc.type: FUNC
1685   * @tc.require:
1686   * @tc.author: bty
1687   */
1688 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql010, TestSize.Level0)
1689 {
1690     /**
1691      * @tc.steps:step1. init db data
1692      * @tc.expected: step1. Return OK.
1693      */
1694     uint64_t num = 10;
1695     CreateMultiTable();
1696     OpenStore();
1697     SqlCondition condition;
1698     Bytes photo = { 1, 2, 3, 4 };
1699     std::vector<VBucket> records;
1700     for (size_t i = 0; i < num; i++) {
1701         condition.sql = "INSERT INTO " + TABLE_NAME2
1702             + " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(i) +
1703             "', '175.8', ?, 'x', '18');";
1704         condition.bindArgs = {photo};
1705         EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1706     }
1707 
1708     /**
1709      * @tc.steps:step2. ExecuteSql with transaction
1710      * @tc.expected: step2. Return OK.
1711      */
1712     condition.sql = "create temp table AA as select * from " + TABLE_NAME2;
1713     condition.bindArgs = {};
1714     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1715     condition.sql = "select * from " + TABLE_NAME2;
1716     condition.readOnly = true;
1717     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1718     EXPECT_EQ(records.size(), num);
1719     CloseStore();
1720 }
1721 
1722 /**
1723   * @tc.name: TrackerTableTest026
1724   * @tc.desc: Test tracker table with case sensitive table name
1725   * @tc.type: FUNC
1726   * @tc.require:
1727   * @tc.author: bty
1728   */
1729 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest026, TestSize.Level0)
1730 {
1731     /**
1732      * @tc.steps:step1. SetTrackerTable on table2
1733      * @tc.expected: step1. Return OK.
1734      */
1735     CreateMultiTable();
1736     OpenStore();
1737     TrackerSchema schema = g_normalSchema1;
1738     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1739 
1740     /**
1741      * @tc.steps:step2. SetTrackerTable on table2 with case different
1742      * @tc.expected: step2. Return NOT_FOUND.
1743      */
1744     schema.tableName = "worker2";
1745     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1746     uint64_t num = 10;
1747     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1748     schema.tableName = "workeR2";
1749     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1750     schema.trackerColNames = {};
1751     schema.tableName = "WorkeR2";
1752     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1753     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1754 
1755     schema = g_normalSchema1;
1756     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1757     CloseStore();
1758 }
1759 
1760 /**
1761   * @tc.name: TrackerTableTest027
1762   * @tc.desc: Test tracker table with case sensitive distributed table name
1763   * @tc.type: FUNC
1764   * @tc.require:
1765   * @tc.author: bty
1766   */
1767 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest027, TestSize.Level0)
1768 {
1769     /**
1770      * @tc.steps:step1. create distributed table on table2 with case different
1771      * @tc.expected: step1. Return OK.
1772      */
1773     CreateMultiTable();
1774     OpenStore();
1775     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1776     TrackerSchema schema = g_normalSchema1;
1777     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1778     EXPECT_EQ(g_delegate->CreateDistributedTable("worker2", CLOUD_COOPERATION), DBStatus::OK);
1779 
1780     /**
1781      * @tc.steps:step2. SetTrackerTable on table2 with case different
1782      * @tc.expected: step2. Return NOT_FOUND.
1783      */
1784     schema.tableName = "Worker2";
1785     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1786     uint64_t num = 10;
1787     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1788     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1789     schema.tableName = "WOrker2";
1790     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1791     schema.trackerColNames = {};
1792     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1793     schema.tableName = "Worker2";
1794     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1795 
1796     /**
1797      * @tc.steps:step3. SetTrackerTable with "worKer2"
1798      * @tc.expected: step3. Return NOT_FOUND.
1799      */
1800     schema.tableName = g_normalSchema1.tableName;
1801     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1802 
1803     /**
1804      * @tc.steps:step4. SetTrackerTable with "worKer2" after reopening db
1805      * @tc.expected: step4. Return OK.
1806      */
1807     CloseStore();
1808     OpenStore();
1809     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1810     schema.trackerColNames = {};
1811     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1812     CloseStore();
1813 }
1814 
1815 /**
1816   * @tc.name: TrackerTableTest030
1817   * @tc.desc: Test clean trackTable when table is distributedTable
1818   * @tc.type: FUNC
1819   * @tc.require:
1820   * @tc.author: wangxiangdong
1821   */
1822 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest030, TestSize.Level0)
1823 {
1824     /**
1825      * @tc.steps:step1. SetTrackerTable
1826      * @tc.expected: step1. Return OK.
1827      */
1828     CreateMultiTable();
1829 
1830     OpenStore();
1831     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2), OK);
1832 
1833     /**
1834      * @tc.steps:step2. Insert data to table2
1835      * @tc.expected: step2. Return E_OK.
1836      */
1837     uint64_t num = 10;
1838     BatchInsertTableName2Data(num);
1839     BatchDeleteTableName2Data(num / HALF);
1840 
1841     /**
1842      * @tc.steps:step3. CleanTrackerData
1843      * @tc.expected: step3. Return OK.
1844      */
1845     EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK);
1846     std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
1847         " where extend_field is NULL;";
1848     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1849         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
1850     CloseStore();
1851 }
1852 
1853 /**
1854   * @tc.name: SchemaStrTest001
1855   * @tc.desc: Test open reOpen stroe when schemaStr is empty
1856   * @tc.type: FUNC
1857   * @tc.require:
1858   * @tc.author: bty
1859   */
1860 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, SchemaStrTest001, TestSize.Level0)
1861 {
1862     /**
1863      * @tc.steps:step1. set empty for relational schema str, reopen store
1864      * @tc.expected: step1. Return OK.
1865      */
1866     std::string updMetaSql = "UPDATE naturalbase_rdb_aux_metadata SET value=? where key=?;";
1867     CreateMultiTable();
1868     OpenStore();
1869     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1870     SqlCondition condition;
1871     std::vector<VBucket> records;
1872     condition.sql = updMetaSql;
1873     Key relationKey;
1874     DBCommon::StringToVector(DBConstant::RELATIONAL_SCHEMA_KEY, relationKey);
1875     condition.bindArgs = { std::string(""), relationKey };
1876     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1877     CloseStore();
1878     OpenStore();
1879 
1880     /**
1881      * @tc.steps:step2. set empty for relational schema str, reopen store to upgrade
1882      * @tc.expected: step2. Return OK.
1883      */
1884     Value verVal;
1885     DBCommon::StringToVector("5.0", verVal);
1886     Key verKey;
1887     DBCommon::StringToVector("log_table_version", verKey);
1888     condition.bindArgs = { verVal, verKey };
1889     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1890     condition.bindArgs = { std::string(""), relationKey };
1891     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1892     CloseStore();
1893     OpenStore();
1894 
1895     /**
1896      * @tc.steps:step3. set empty for tracker schema str, reopen store to upgrade
1897      * @tc.expected: step3. Return OK.
1898      */
1899     TrackerSchema schema = g_normalSchema1;
1900     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1901     condition.bindArgs = { verVal, verKey };
1902     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1903     condition.bindArgs = { std::string(""), relationKey };
1904     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1905     Key trackerKey;
1906     DBCommon::StringToVector("relational_tracker_schema", trackerKey);
1907     condition.bindArgs = { std::string(""), trackerKey };
1908     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1909     CloseStore();
1910     OpenStore();
1911 
1912     /**
1913      * @tc.steps:step4. try to create distributed table and set tracker table again
1914      * @tc.expected: step4. Return OK.
1915      */
1916     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1917     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME1, CLOUD_COOPERATION), DBStatus::OK);
1918     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1919     CloseStore();
1920 }
1921 }