lbug 0.12.3-dev.2 → 0.12.3-dev.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -6
- package/lbug-source/.github/workflows/ci-workflow.yml +9 -2
- package/lbug-source/CMakeLists.txt +15 -6
- package/lbug-source/Makefile +1 -2
- package/lbug-source/README.md +2 -6
- package/lbug-source/benchmark/serializer.py +24 -3
- package/lbug-source/dataset/demo-db/csv/copy.cypher +4 -4
- package/lbug-source/dataset/demo-db/graph-std/demo_indices_follows.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_indices_livesin.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_indptr_follows.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_indptr_livesin.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_mapping_city.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_mapping_user.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_metadata.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_nodes_city.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/demo_nodes_user.parquet +0 -0
- package/lbug-source/dataset/demo-db/graph-std/schema.cypher +4 -0
- package/lbug-source/dataset/demo-db/parquet/copy.cypher +4 -4
- package/lbug-source/extension/httpfs/test/test_files/http.test +1 -0
- package/lbug-source/scripts/antlr4/Cypher.g4 +1 -1
- package/lbug-source/scripts/antlr4/hash.md5 +1 -1
- package/lbug-source/scripts/generate_binary_demo.sh +1 -1
- package/lbug-source/src/antlr4/Cypher.g4 +1 -1
- package/lbug-source/src/binder/bind/bind_ddl.cpp +23 -13
- package/lbug-source/src/catalog/catalog.cpp +5 -4
- package/lbug-source/src/catalog/catalog_entry/node_table_catalog_entry.cpp +8 -1
- package/lbug-source/src/catalog/catalog_entry/rel_group_catalog_entry.cpp +7 -0
- package/lbug-source/src/function/function_collection.cpp +2 -1
- package/lbug-source/src/function/table/CMakeLists.txt +1 -0
- package/lbug-source/src/function/table/disk_size_info.cpp +322 -0
- package/lbug-source/src/include/binder/ddl/bound_create_table_info.h +10 -6
- package/lbug-source/src/include/catalog/catalog_entry/node_table_catalog_entry.h +5 -3
- package/lbug-source/src/include/catalog/catalog_entry/rel_group_catalog_entry.h +4 -2
- package/lbug-source/src/include/common/constants.h +1 -0
- package/lbug-source/src/include/function/table/simple_table_function.h +6 -0
- package/lbug-source/src/include/optimizer/count_rel_table_optimizer.h +49 -0
- package/lbug-source/src/include/optimizer/logical_operator_visitor.h +6 -0
- package/lbug-source/src/include/parser/ddl/create_table_info.h +3 -1
- package/lbug-source/src/include/planner/operator/logical_operator.h +1 -0
- package/lbug-source/src/include/planner/operator/scan/logical_count_rel_table.h +84 -0
- package/lbug-source/src/include/processor/operator/physical_operator.h +1 -0
- package/lbug-source/src/include/processor/operator/scan/count_rel_table.h +62 -0
- package/lbug-source/src/include/processor/operator/scan/scan_node_table.h +2 -2
- package/lbug-source/src/include/processor/plan_mapper.h +2 -0
- package/lbug-source/src/include/storage/storage_manager.h +1 -0
- package/lbug-source/src/include/storage/storage_version_info.h +1 -7
- package/lbug-source/src/include/storage/table/node_table.h +6 -1
- package/lbug-source/src/include/storage/table/parquet_node_table.h +103 -0
- package/lbug-source/src/include/storage/table/parquet_rel_table.h +91 -0
- package/lbug-source/src/include/storage/table/rel_table.h +2 -2
- package/lbug-source/src/include/transaction/transaction.h +2 -0
- package/lbug-source/src/main/query_result/materialized_query_result.cpp +2 -2
- package/lbug-source/src/optimizer/CMakeLists.txt +1 -0
- package/lbug-source/src/optimizer/count_rel_table_optimizer.cpp +217 -0
- package/lbug-source/src/optimizer/logical_operator_visitor.cpp +6 -0
- package/lbug-source/src/optimizer/optimizer.cpp +6 -0
- package/lbug-source/src/parser/transform/transform_ddl.cpp +6 -1
- package/lbug-source/src/planner/operator/logical_operator.cpp +2 -0
- package/lbug-source/src/planner/operator/scan/CMakeLists.txt +1 -0
- package/lbug-source/src/planner/operator/scan/logical_count_rel_table.cpp +24 -0
- package/lbug-source/src/processor/map/CMakeLists.txt +1 -0
- package/lbug-source/src/processor/map/map_count_rel_table.cpp +55 -0
- package/lbug-source/src/processor/map/plan_mapper.cpp +3 -0
- package/lbug-source/src/processor/operator/persistent/reader/parquet/parquet_reader.cpp +4 -0
- package/lbug-source/src/processor/operator/physical_operator.cpp +2 -0
- package/lbug-source/src/processor/operator/scan/CMakeLists.txt +1 -0
- package/lbug-source/src/processor/operator/scan/count_rel_table.cpp +137 -0
- package/lbug-source/src/processor/operator/scan/scan_multi_rel_tables.cpp +24 -2
- package/lbug-source/src/processor/operator/scan/scan_node_table.cpp +44 -8
- package/lbug-source/src/processor/operator/scan/scan_rel_table.cpp +12 -2
- package/lbug-source/src/storage/storage_manager.cpp +37 -6
- package/lbug-source/src/storage/table/CMakeLists.txt +2 -0
- package/lbug-source/src/storage/table/parquet_node_table.cpp +338 -0
- package/lbug-source/src/storage/table/parquet_rel_table.cpp +388 -0
- package/lbug-source/test/api/api_test.cpp +18 -0
- package/lbug-source/test/common/string_format.cpp +9 -1
- package/lbug-source/test/copy/copy_test.cpp +4 -4
- package/lbug-source/test/graph_test/CMakeLists.txt +1 -1
- package/lbug-source/test/include/test_runner/test_group.h +11 -1
- package/lbug-source/test/optimizer/optimizer_test.cpp +46 -0
- package/lbug-source/test/runner/e2e_test.cpp +7 -1
- package/lbug-source/test/test_files/demo_db/demo_db_graph_std.test +77 -0
- package/lbug-source/test/test_helper/CMakeLists.txt +1 -1
- package/lbug-source/test/test_helper/test_helper.cpp +33 -1
- package/lbug-source/test/test_runner/CMakeLists.txt +1 -1
- package/lbug-source/test/test_runner/insert_by_row.cpp +6 -8
- package/lbug-source/test/test_runner/multi_copy_split.cpp +2 -4
- package/lbug-source/test/test_runner/test_parser.cpp +3 -0
- package/lbug-source/test/transaction/checkpoint_test.cpp +1 -1
- package/lbug-source/test/transaction/transaction_test.cpp +19 -15
- package/lbug-source/third_party/antlr4_cypher/cypher_parser.cpp +2761 -2701
- package/lbug-source/third_party/antlr4_cypher/include/cypher_parser.h +2 -0
- package/lbug-source/tools/benchmark/count_rel_table.benchmark +5 -0
- package/lbug-source/tools/shell/embedded_shell.cpp +78 -3
- package/lbug-source/tools/shell/include/embedded_shell.h +2 -0
- package/lbug-source/tools/shell/linenoise.cpp +3 -3
- package/lbug-source/tools/shell/test/test_helper.py +1 -1
- package/lbug-source/tools/shell/test/test_shell_basics.py +12 -0
- package/lbug-source/tools/shell/test/test_shell_commands.py +19 -0
- package/package.json +1 -1
- package/prebuilt/lbugjs-darwin-arm64.node +0 -0
- package/prebuilt/lbugjs-linux-arm64.node +0 -0
- package/prebuilt/lbugjs-linux-x64.node +0 -0
- package/prebuilt/lbugjs-win32-x64.node +0 -0
|
@@ -32,6 +32,7 @@ void TestHelper::executeScript(const std::string& cypherScript, Connection& conn
|
|
|
32
32
|
std::cout << "cypherScript: " << cypherScript << " doesn't exist. Skipping..." << std::endl;
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
|
+
auto cypherDir = std::filesystem::path(cypherScript).parent_path();
|
|
35
36
|
std::ifstream file(cypherScript);
|
|
36
37
|
if (!file.is_open()) {
|
|
37
38
|
throw Exception(stringFormat("Error opening file: {}, errno: {}.", cypherScript, errno));
|
|
@@ -68,9 +69,40 @@ void TestHelper::executeScript(const std::string& cypherScript, Connection& conn
|
|
|
68
69
|
index = end + 1;
|
|
69
70
|
}
|
|
70
71
|
for (auto& csvFilePath : csvFilePaths) {
|
|
71
|
-
|
|
72
|
+
std::string fullPath = csvFilePath;
|
|
73
|
+
if (std::filesystem::path(csvFilePath).is_relative()) {
|
|
74
|
+
if (std::filesystem::path(csvFilePath).parent_path().empty()) {
|
|
75
|
+
fullPath = (cypherDir / csvFilePath).string();
|
|
76
|
+
} else {
|
|
77
|
+
fullPath = appendLbugRootPath(csvFilePath);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
72
80
|
line.replace(line.find(csvFilePath), csvFilePath.length(), fullPath);
|
|
73
81
|
}
|
|
82
|
+
// Also handle storage = 'path' for parquet tables
|
|
83
|
+
std::vector<std::string> storagePaths;
|
|
84
|
+
size_t storageIndex = 0;
|
|
85
|
+
while (true) {
|
|
86
|
+
size_t start = line.find("storage = '", storageIndex);
|
|
87
|
+
if (start == std::string::npos) {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
start += 11; // length of "storage = '"
|
|
91
|
+
size_t end = line.find("'", start);
|
|
92
|
+
if (end == std::string::npos) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
std::string storagePath = line.substr(start, end - start);
|
|
96
|
+
storagePaths.push_back(storagePath);
|
|
97
|
+
storageIndex = end + 1;
|
|
98
|
+
}
|
|
99
|
+
for (auto& storagePath : storagePaths) {
|
|
100
|
+
auto fullPath = appendLbugRootPath(storagePath);
|
|
101
|
+
size_t pos = line.find(storagePath);
|
|
102
|
+
if (pos != std::string::npos) {
|
|
103
|
+
line.replace(pos, storagePath.length(), fullPath);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
74
106
|
#ifdef __STATIC_LINK_EXTENSION_TEST__
|
|
75
107
|
if (line.starts_with("load extension")) {
|
|
76
108
|
continue;
|
|
@@ -111,23 +111,21 @@ std::string InsertDatasetByRow::TableInfo::getBodyForLoad() const {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
std::string InsertDatasetByRow::NodeTableInfo::getLoadFromQuery() const {
|
|
114
|
-
const std::string query = "LOAD WITH HEADERS ({}) FROM {} "
|
|
115
|
-
"CREATE (:{} {});";
|
|
116
114
|
const auto header = getHeaderForLoad();
|
|
117
115
|
const auto body = getBodyForLoad();
|
|
118
|
-
return stringFormat(
|
|
116
|
+
return stringFormat("LOAD WITH HEADERS ({}) FROM {} CREATE (:{} {{{}}});", header, filePath,
|
|
117
|
+
name, body);
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
std::string InsertDatasetByRow::RelTableInfo::getLoadFromQuery() const {
|
|
122
|
-
const std::string query = "LOAD WITH HEADERS ({}) FROM {} "
|
|
123
|
-
"MATCH (a:{}), (b:{}) WHERE a.{} = aid_ AND b.{} = bid_ "
|
|
124
|
-
"CREATE (a)-[:{} {}]->(b);";
|
|
125
121
|
auto header = stringFormat("aid_ {},bid_ {}", from.type, to.type);
|
|
126
122
|
auto headerRest = getHeaderForLoad();
|
|
127
123
|
header += headerRest.length() == 0 ? "" : "," + getHeaderForLoad();
|
|
128
124
|
const auto body = getBodyForLoad();
|
|
129
|
-
return stringFormat(
|
|
130
|
-
|
|
125
|
+
return stringFormat("LOAD WITH HEADERS ({}) FROM {} "
|
|
126
|
+
"MATCH (a:{}), (b:{}) WHERE a.{} = aid_ AND b.{} = bid_ "
|
|
127
|
+
"CREATE (a)-[:{} {{{}}}]->(b);",
|
|
128
|
+
header, filePath, from.name, to.name, from.property, to.property, name, body);
|
|
131
129
|
}
|
|
132
130
|
|
|
133
131
|
} // namespace testing
|
|
@@ -62,8 +62,7 @@ void SplitMultiCopyRandom::init() {
|
|
|
62
62
|
|
|
63
63
|
const std::string tmpDir = TestHelper::getTempDir("multi_copy");
|
|
64
64
|
auto totalFilePath = TestHelper::joinPath(tmpDir, tableName + ".csv");
|
|
65
|
-
|
|
66
|
-
loadQuery = stringFormat(loadQuery, source, totalFilePath);
|
|
65
|
+
auto loadQuery = stringFormat("COPY (LOAD FROM {} RETURN *) TO '{}';", source, totalFilePath);
|
|
67
66
|
spdlog::info("QUERY: {}", loadQuery);
|
|
68
67
|
validateQuery(connection, loadQuery);
|
|
69
68
|
|
|
@@ -96,9 +95,8 @@ void SplitMultiCopyRandom::init() {
|
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
void SplitMultiCopyRandom::run() {
|
|
99
|
-
const std::string query = "COPY {} FROM \"{}\";";
|
|
100
98
|
for (auto file : splitFilePaths) {
|
|
101
|
-
auto currQuery = stringFormat(
|
|
99
|
+
auto currQuery = stringFormat("COPY {} FROM \"{}\";", tableName, file);
|
|
102
100
|
spdlog::info("QUERY: {}", currQuery);
|
|
103
101
|
validateQuery(connection, currQuery);
|
|
104
102
|
}
|
|
@@ -87,6 +87,9 @@ void TestParser::extractDataset() {
|
|
|
87
87
|
testGroup->datasetType = TestGroup::DatasetType::JSON;
|
|
88
88
|
testGroup->dataset = currentToken.params[2];
|
|
89
89
|
}
|
|
90
|
+
} else if (datasetType == "GRAPH-STD") {
|
|
91
|
+
testGroup->datasetType = TestGroup::DatasetType::GRAPH_STD;
|
|
92
|
+
testGroup->dataset = currentToken.params[2];
|
|
90
93
|
} else {
|
|
91
94
|
throw TestException(
|
|
92
95
|
"Invalid dataset type `" + currentToken.params[1] + "` [" + path + ":" + line + "].");
|
|
@@ -37,7 +37,7 @@ public:
|
|
|
37
37
|
conn->query("CALL auto_checkpoint=false");
|
|
38
38
|
conn->query("CREATE NODE TABLE test(id INT64 PRIMARY KEY, name STRING);");
|
|
39
39
|
for (auto i = 0; i < 5000; i++) {
|
|
40
|
-
conn->query(stringFormat("CREATE (a:test {id: {}, name: 'name_{}'});", i, i));
|
|
40
|
+
conn->query(stringFormat("CREATE (a:test {{id: {}, name: 'name_{}'}});", i, i));
|
|
41
41
|
}
|
|
42
42
|
auto context = getClientContext(*conn);
|
|
43
43
|
flakyCheckpointer.setCheckpointer(*context);
|
|
@@ -138,7 +138,8 @@ static void insertNodes(uint64_t startID, uint64_t num, lbug::main::Database& da
|
|
|
138
138
|
auto conn = std::make_unique<lbug::main::Connection>(&database);
|
|
139
139
|
for (uint64_t i = 0; i < num; ++i) {
|
|
140
140
|
auto id = startID + i;
|
|
141
|
-
auto res =
|
|
141
|
+
auto res =
|
|
142
|
+
conn->query(stringFormat("CREATE (:test {{id: {}, name: 'Person{}'}});", id, id));
|
|
142
143
|
ASSERT_TRUE(res->isSuccess())
|
|
143
144
|
<< "Failed to insert test" << id << ": " << res->getErrorMessage();
|
|
144
145
|
}
|
|
@@ -181,7 +182,7 @@ static void insertNodesWithMixedTypes(uint64_t startID, uint64_t num,
|
|
|
181
182
|
auto score = 95.5 + (id % 10);
|
|
182
183
|
auto isActive = (id % 2 == 0) ? "true" : "false";
|
|
183
184
|
auto res = conn->query(
|
|
184
|
-
stringFormat("CREATE (:mixed_test {id: {}, score: {}, active: {}, name: 'User{}'});",
|
|
185
|
+
stringFormat("CREATE (:mixed_test {{id: {}, score: {}, active: {}, name: 'User{}'}});",
|
|
185
186
|
id, score, isActive, id));
|
|
186
187
|
ASSERT_TRUE(res->isSuccess())
|
|
187
188
|
<< "Failed to insert mixed_test" << id << ": " << res->getErrorMessage();
|
|
@@ -227,7 +228,7 @@ static void insertRelationships(uint64_t startID, uint64_t num, lbug::main::Data
|
|
|
227
228
|
auto toID = (startID + i + 1) % (num * 4);
|
|
228
229
|
auto weight = 1.0 + (i % 10) * 0.1;
|
|
229
230
|
auto res = conn->query(stringFormat("MATCH (a:person), (b:person) WHERE a.id = {} AND b.id "
|
|
230
|
-
"= {} CREATE (a)-[:knows {weight: {}}]->(b);",
|
|
231
|
+
"= {} CREATE (a)-[:knows {{weight: {}}}]->(b);",
|
|
231
232
|
fromID, toID, weight));
|
|
232
233
|
ASSERT_TRUE(res->isSuccess()) << "Failed to insert relationship from " << fromID << " to "
|
|
233
234
|
<< toID << ": " << res->getErrorMessage();
|
|
@@ -248,7 +249,8 @@ TEST_F(EmptyDBTransactionTest, ConcurrentRelationshipInsertions) {
|
|
|
248
249
|
|
|
249
250
|
conn->query("BEGIN TRANSACTION;");
|
|
250
251
|
for (auto i = 0; i < numTotalInsertions; ++i) {
|
|
251
|
-
auto res =
|
|
252
|
+
auto res =
|
|
253
|
+
conn->query(stringFormat("CREATE (:person {{id: {}, name: 'Person{}'}});", i, i));
|
|
252
254
|
ASSERT_TRUE(res->isSuccess());
|
|
253
255
|
}
|
|
254
256
|
conn->query("COMMIT;");
|
|
@@ -286,7 +288,7 @@ static void insertComplexRelationships(uint64_t startID, uint64_t num,
|
|
|
286
288
|
auto isVerified = (i % 3 == 0) ? "true" : "false";
|
|
287
289
|
auto res =
|
|
288
290
|
conn->query(stringFormat("MATCH (u:user), (p:product) WHERE u.id = {} AND p.id = {} "
|
|
289
|
-
"CREATE (u)-[:rates {rating: {}, verified: {}}]->(p);",
|
|
291
|
+
"CREATE (u)-[:rates {{rating: {}, verified: {}}}]->(p);",
|
|
290
292
|
userID, productID, rating, isVerified));
|
|
291
293
|
ASSERT_TRUE(res->isSuccess())
|
|
292
294
|
<< "Failed to insert rating from user " << userID << " to product " << productID << ": "
|
|
@@ -309,12 +311,12 @@ TEST_F(EmptyDBTransactionTest, ConcurrentComplexRelationshipInsertions) {
|
|
|
309
311
|
|
|
310
312
|
conn->query("BEGIN TRANSACTION;");
|
|
311
313
|
for (auto i = 0; i < numTotalInsertions; ++i) {
|
|
312
|
-
auto res = conn->query(stringFormat("CREATE (:user {id: {}, name: 'User{}'});", i, i));
|
|
314
|
+
auto res = conn->query(stringFormat("CREATE (:user {{id: {}, name: 'User{}'}});", i, i));
|
|
313
315
|
ASSERT_TRUE(res->isSuccess());
|
|
314
316
|
}
|
|
315
317
|
for (auto i = 0; i < numTotalInsertions * 2; ++i) {
|
|
316
318
|
auto res =
|
|
317
|
-
conn->query(stringFormat("CREATE (:product {id: {}, title: 'Product{}'});", i, i));
|
|
319
|
+
conn->query(stringFormat("CREATE (:product {{id: {}, title: 'Product{}'}});", i, i));
|
|
318
320
|
ASSERT_TRUE(res->isSuccess());
|
|
319
321
|
}
|
|
320
322
|
conn->query("COMMIT;");
|
|
@@ -367,7 +369,7 @@ TEST_F(EmptyDBTransactionTest, ConcurrentNodeUpdates) {
|
|
|
367
369
|
|
|
368
370
|
// First insert all nodes
|
|
369
371
|
for (auto i = 0; i < numTotalNodes; ++i) {
|
|
370
|
-
auto res = conn->query(stringFormat("CREATE (:test {id: {}, name: 'Person{}'});", i, i));
|
|
372
|
+
auto res = conn->query(stringFormat("CREATE (:test {{id: {}, name: 'Person{}'}});", i, i));
|
|
371
373
|
ASSERT_TRUE(res->isSuccess());
|
|
372
374
|
}
|
|
373
375
|
|
|
@@ -429,8 +431,8 @@ TEST_F(EmptyDBTransactionTest, ConcurrentMixedTypeUpdates) {
|
|
|
429
431
|
auto score = 95.5 + (i % 10);
|
|
430
432
|
auto isActive = (i % 2 == 0) ? "true" : "false";
|
|
431
433
|
auto res = conn->query(
|
|
432
|
-
stringFormat("CREATE (:mixed_test {id: {}, score: {}, active: {}, name: 'User{}'});",
|
|
433
|
-
score, isActive, i));
|
|
434
|
+
stringFormat("CREATE (:mixed_test {{id: {}, score: {}, active: {}, name: 'User{}'}});",
|
|
435
|
+
i, score, isActive, i));
|
|
434
436
|
ASSERT_TRUE(res->isSuccess());
|
|
435
437
|
}
|
|
436
438
|
|
|
@@ -503,7 +505,8 @@ TEST_F(EmptyDBTransactionTest, ConcurrentRelationshipUpdates) {
|
|
|
503
505
|
|
|
504
506
|
// Create nodes
|
|
505
507
|
for (auto i = 0; i < numTotalUpdates; ++i) {
|
|
506
|
-
auto res =
|
|
508
|
+
auto res =
|
|
509
|
+
conn->query(stringFormat("CREATE (:person {{id: {}, name: 'Person{}'}});", i, i));
|
|
507
510
|
ASSERT_TRUE(res->isSuccess());
|
|
508
511
|
}
|
|
509
512
|
|
|
@@ -513,7 +516,7 @@ TEST_F(EmptyDBTransactionTest, ConcurrentRelationshipUpdates) {
|
|
|
513
516
|
auto toID = (i + 1) % numTotalUpdates;
|
|
514
517
|
auto weight = 1.0 + (i % 10) * 0.1;
|
|
515
518
|
auto res = conn->query(stringFormat("MATCH (a:person), (b:person) WHERE a.id = {} AND b.id "
|
|
516
|
-
"= {} CREATE (a)-[:knows {weight: {}}]->(b);",
|
|
519
|
+
"= {} CREATE (a)-[:knows {{weight: {}}}]->(b);",
|
|
517
520
|
fromID, toID, weight));
|
|
518
521
|
ASSERT_TRUE(res->isSuccess());
|
|
519
522
|
}
|
|
@@ -577,7 +580,7 @@ TEST_F(EmptyDBTransactionTest, ConcurrentNodeUpdatesWithMixedTransactions) {
|
|
|
577
580
|
|
|
578
581
|
// Insert initial nodes
|
|
579
582
|
for (auto i = 0; i < numTotalNodes; ++i) {
|
|
580
|
-
auto res = conn->query(stringFormat("CREATE (:test {id: {}, name: 'Person{}'});", i, i));
|
|
583
|
+
auto res = conn->query(stringFormat("CREATE (:test {{id: {}, name: 'Person{}'}});", i, i));
|
|
581
584
|
ASSERT_TRUE(res->isSuccess());
|
|
582
585
|
}
|
|
583
586
|
|
|
@@ -650,7 +653,8 @@ TEST_F(EmptyDBTransactionTest, ConcurrentRelationshipUpdatesWithMixedTransaction
|
|
|
650
653
|
|
|
651
654
|
// Create nodes
|
|
652
655
|
for (auto i = 0; i < numTotalUpdates; ++i) {
|
|
653
|
-
auto res =
|
|
656
|
+
auto res =
|
|
657
|
+
conn->query(stringFormat("CREATE (:person {{id: {}, name: 'Person{}'}});", i, i));
|
|
654
658
|
ASSERT_TRUE(res->isSuccess());
|
|
655
659
|
}
|
|
656
660
|
|
|
@@ -660,7 +664,7 @@ TEST_F(EmptyDBTransactionTest, ConcurrentRelationshipUpdatesWithMixedTransaction
|
|
|
660
664
|
auto toID = i;
|
|
661
665
|
auto weight = 20.0;
|
|
662
666
|
auto res = conn->query(stringFormat("MATCH (a:person), (b:person) WHERE a.id = {} AND b.id "
|
|
663
|
-
"= {} CREATE (a)-[:knows {weight: {}}]->(b);",
|
|
667
|
+
"= {} CREATE (a)-[:knows {{weight: {}}}]->(b);",
|
|
664
668
|
fromID, toID, weight));
|
|
665
669
|
ASSERT_TRUE(res->isSuccess());
|
|
666
670
|
}
|