lbug 0.12.3-dev.9 → 0.13.1-dev.1
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/lbug-source/.github/workflows/ci-workflow.yml +9 -2
- package/lbug-source/CMakeLists.txt +15 -6
- package/lbug-source/Makefile +15 -4
- 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/duckdb/src/catalog/duckdb_catalog.cpp +1 -1
- package/lbug-source/extension/duckdb/src/catalog/duckdb_table_catalog_entry.cpp +43 -4
- package/lbug-source/extension/duckdb/src/connector/duckdb_result_converter.cpp +6 -0
- package/lbug-source/extension/duckdb/src/connector/duckdb_secret_manager.cpp +1 -1
- package/lbug-source/extension/duckdb/src/function/duckdb_scan.cpp +49 -4
- package/lbug-source/extension/duckdb/src/include/catalog/duckdb_table_catalog_entry.h +6 -1
- package/lbug-source/extension/duckdb/src/include/function/duckdb_scan.h +2 -0
- package/lbug-source/extension/duckdb/test/test_files/duckdb.test +28 -0
- package/lbug-source/extension/extension_config.cmake +3 -2
- package/lbug-source/extension/httpfs/test/test_files/http.test +1 -0
- package/lbug-source/scripts/antlr4/Cypher.g4 +4 -4
- package/lbug-source/scripts/antlr4/hash.md5 +1 -1
- package/lbug-source/scripts/extension/PRODUCTION_RELEASES +1 -0
- package/lbug-source/scripts/generate_binary_demo.sh +1 -1
- package/lbug-source/src/antlr4/Cypher.g4 +4 -4
- package/lbug-source/src/binder/bind/bind_ddl.cpp +97 -15
- package/lbug-source/src/binder/bind/bind_graph_pattern.cpp +30 -3
- package/lbug-source/src/catalog/catalog.cpp +6 -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 +46 -7
- package/lbug-source/src/catalog/catalog_set.cpp +1 -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/function/table/show_connection.cpp +6 -1
- package/lbug-source/src/function/table/show_tables.cpp +10 -2
- package/lbug-source/src/function/table/table_function.cpp +11 -2
- package/lbug-source/src/include/binder/ddl/bound_create_table_info.h +23 -6
- package/lbug-source/src/include/binder/expression/variable_expression.h +1 -1
- 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 +21 -2
- package/lbug-source/src/include/catalog/catalog_entry/table_catalog_entry.h +7 -0
- package/lbug-source/src/include/common/constants.h +1 -0
- package/lbug-source/src/include/common/string_format.h +2 -2
- package/lbug-source/src/include/common/types/types.h +1 -0
- package/lbug-source/src/include/function/table/bind_data.h +12 -1
- package/lbug-source/src/include/function/table/simple_table_function.h +6 -0
- package/lbug-source/src/include/function/table/table_function.h +2 -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/optimizer/order_by_push_down_optimizer.h +21 -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/logical_table_function_call.h +14 -1
- 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 -1
- package/lbug-source/src/include/storage/table/foreign_rel_table.h +56 -0
- 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/optimizer/CMakeLists.txt +3 -1
- package/lbug-source/src/optimizer/count_rel_table_optimizer.cpp +217 -0
- package/lbug-source/src/optimizer/limit_push_down_optimizer.cpp +12 -0
- package/lbug-source/src/optimizer/logical_operator_visitor.cpp +6 -0
- package/lbug-source/src/optimizer/optimizer.cpp +10 -0
- package/lbug-source/src/optimizer/order_by_push_down_optimizer.cpp +123 -0
- package/lbug-source/src/optimizer/projection_push_down_optimizer.cpp +5 -1
- package/lbug-source/src/parser/transform/transform_ddl.cpp +6 -1
- package/lbug-source/src/parser/transform/transform_expression.cpp +1 -1
- package/lbug-source/src/parser/transform/transform_graph_pattern.cpp +6 -1
- package/lbug-source/src/parser/transformer.cpp +7 -1
- package/lbug-source/src/planner/join_order/cardinality_estimator.cpp +11 -2
- package/lbug-source/src/planner/operator/logical_operator.cpp +2 -0
- package/lbug-source/src/planner/operator/logical_table_function_call.cpp +4 -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/planner/plan/plan_join_order.cpp +16 -1
- 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/index_lookup.cpp +31 -23
- 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 +18 -2
- package/lbug-source/src/storage/storage_manager.cpp +43 -6
- package/lbug-source/src/storage/table/CMakeLists.txt +3 -0
- package/lbug-source/src/storage/table/foreign_rel_table.cpp +63 -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/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 +2805 -2708
- package/lbug-source/third_party/antlr4_cypher/include/cypher_parser.h +7 -3
- package/lbug-source/tools/benchmark/count_rel_table.benchmark +5 -0
- package/lbug-source/tools/nodejs_api/package.json +4 -2
- 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 +9 -2
- 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
|
@@ -687,6 +687,8 @@ public:
|
|
|
687
687
|
antlr4::tree::TerminalNode *AS();
|
|
688
688
|
OC_QueryContext *oC_Query();
|
|
689
689
|
KU_IfNotExistsContext *kU_IfNotExists();
|
|
690
|
+
antlr4::tree::TerminalNode *WITH();
|
|
691
|
+
KU_OptionsContext *kU_Options();
|
|
690
692
|
KU_CreateNodeConstraintContext *kU_CreateNodeConstraint();
|
|
691
693
|
|
|
692
694
|
|
|
@@ -2160,7 +2162,8 @@ public:
|
|
|
2160
2162
|
public:
|
|
2161
2163
|
OC_LabelNameContext(antlr4::ParserRuleContext *parent, size_t invokingState);
|
|
2162
2164
|
virtual size_t getRuleIndex() const override;
|
|
2163
|
-
OC_SchemaNameContext
|
|
2165
|
+
std::vector<OC_SchemaNameContext *> oC_SchemaName();
|
|
2166
|
+
OC_SchemaNameContext* oC_SchemaName(size_t i);
|
|
2164
2167
|
|
|
2165
2168
|
|
|
2166
2169
|
};
|
|
@@ -2882,7 +2885,7 @@ public:
|
|
|
2882
2885
|
public:
|
|
2883
2886
|
OC_PropertyKeyNameContext(antlr4::ParserRuleContext *parent, size_t invokingState);
|
|
2884
2887
|
virtual size_t getRuleIndex() const override;
|
|
2885
|
-
|
|
2888
|
+
OC_SymbolicNameContext *oC_SymbolicName();
|
|
2886
2889
|
|
|
2887
2890
|
|
|
2888
2891
|
};
|
|
@@ -2916,7 +2919,8 @@ public:
|
|
|
2916
2919
|
public:
|
|
2917
2920
|
OC_SchemaNameContext(antlr4::ParserRuleContext *parent, size_t invokingState);
|
|
2918
2921
|
virtual size_t getRuleIndex() const override;
|
|
2919
|
-
OC_SymbolicNameContext
|
|
2922
|
+
std::vector<OC_SymbolicNameContext *> oC_SymbolicName();
|
|
2923
|
+
OC_SymbolicNameContext* oC_SymbolicName(size_t i);
|
|
2920
2924
|
|
|
2921
2925
|
|
|
2922
2926
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-NAME count_rel_table
|
|
2
|
+
-PRERUN CREATE NODE TABLE account(ID INT64 PRIMARY KEY); CREATE REL TABLE follows(FROM account TO account); COPY account FROM "dataset/snap/amazon0601/parquet/amazon-nodes.parquet"; COPY follows FROM "dataset/snap/amazon0601/parquet/amazon-edges.parquet";
|
|
3
|
+
-QUERY MATCH ()-[r:follows]->() RETURN COUNT(*)
|
|
4
|
+
---- 1
|
|
5
|
+
3387388
|
|
@@ -12,17 +12,19 @@
|
|
|
12
12
|
"types": "./lbug.d.ts"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
+
"files": ["index.js", "index.mjs", "lbug.d.ts", "lbugjs.node"],
|
|
15
16
|
"type": "commonjs",
|
|
16
17
|
"homepage": "https://ladybugdb.com/",
|
|
17
18
|
"repository": {
|
|
18
19
|
"type": "git",
|
|
19
|
-
"url": "https://github.com/LadybugDB/ladybug"
|
|
20
|
+
"url": "git+https://github.com/LadybugDB/ladybug.git"
|
|
20
21
|
},
|
|
21
22
|
"scripts": {
|
|
22
23
|
"test": "mocha test --timeout 20000",
|
|
23
24
|
"clean": "node clean.js",
|
|
24
25
|
"clean-all": "node clean.js all",
|
|
25
|
-
"build": "node build.js"
|
|
26
|
+
"build": "node build.js",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
26
28
|
},
|
|
27
29
|
"author": "Ladybug Team",
|
|
28
30
|
"license": "MIT",
|
|
@@ -17,7 +17,14 @@
|
|
|
17
17
|
|
|
18
18
|
#include "binder/binder.h"
|
|
19
19
|
#include "catalog/catalog.h"
|
|
20
|
+
#include "catalog/catalog_entry/catalog_entry.h"
|
|
21
|
+
#include "catalog/catalog_entry/index_catalog_entry.h"
|
|
22
|
+
#include "catalog/catalog_entry/node_table_catalog_entry.h"
|
|
23
|
+
#include "catalog/catalog_entry/rel_group_catalog_entry.h"
|
|
24
|
+
#include "catalog/catalog_entry/scalar_macro_catalog_entry.h"
|
|
25
|
+
#include "catalog/catalog_entry/sequence_catalog_entry.h"
|
|
20
26
|
#include "common/exception/parser.h"
|
|
27
|
+
#include "extension/extension_manager.h"
|
|
21
28
|
#include "keywords.h"
|
|
22
29
|
#include "parser/parser.h"
|
|
23
30
|
#include "printer/json_printer.h"
|
|
@@ -62,8 +69,9 @@ struct ShellCommand {
|
|
|
62
69
|
const char* HIGHLIGHT = ":highlight";
|
|
63
70
|
const char* ERRORS = ":render_errors";
|
|
64
71
|
const char* COMPLETE = ":render_completion";
|
|
65
|
-
const
|
|
66
|
-
|
|
72
|
+
const char* SCHEMA = ":schema";
|
|
73
|
+
const std::array<const char*, 13> commandList = {HELP, CLEAR, QUIT, MAX_ROWS, MAX_WIDTH, MODE,
|
|
74
|
+
STATS, MULTI, SINGLE, HIGHLIGHT, ERRORS, COMPLETE, SCHEMA};
|
|
67
75
|
} shellCommand;
|
|
68
76
|
|
|
69
77
|
const char* TAB = " ";
|
|
@@ -263,6 +271,22 @@ void completion(const char* buffer, linenoiseCompletions* lc) {
|
|
|
263
271
|
return;
|
|
264
272
|
}
|
|
265
273
|
|
|
274
|
+
// RETURN *; completion for MATCH and CALL queries.
|
|
275
|
+
// Trigger when buffer ends with ')' or ') ' after a MATCH pattern or CALL function.
|
|
276
|
+
if (regex_search(buf, std::regex(R"(\)\s*$)"))) {
|
|
277
|
+
// Check for MATCH pattern: MATCH(var:Table) or MATCH (var:Table)
|
|
278
|
+
bool isMatchQuery =
|
|
279
|
+
regex_search(buf, std::regex(R"(^\s*MATCH\s*\()", std::regex_constants::icase));
|
|
280
|
+
// Check for CALL function: CALL func_name(...) or CALL func_name (...)
|
|
281
|
+
bool isCallFunction =
|
|
282
|
+
regex_search(buf, std::regex(R"(^\s*CALL\s+\w+\s*\()", std::regex_constants::icase));
|
|
283
|
+
if (isMatchQuery || isCallFunction) {
|
|
284
|
+
std::string suffix = buf.back() == ')' ? " RETURN *;" : "RETURN *;";
|
|
285
|
+
linenoiseAddCompletion(lc, (buf + suffix).c_str());
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
266
290
|
// Node table name completion. Match patterns that include an open bracket `(` with no closing
|
|
267
291
|
// bracket `)`, and a colon `:` sometime after the open bracket.
|
|
268
292
|
if (regex_search(buf, std::regex("^[^]*\\([^\\)]*:[^\\)]*$"))) {
|
|
@@ -413,6 +437,8 @@ int EmbeddedShell::processShellCommands(std::string lineStr) {
|
|
|
413
437
|
setErrors(arg);
|
|
414
438
|
} else if (command == shellCommand.COMPLETE) {
|
|
415
439
|
setComplete(arg);
|
|
440
|
+
} else if (command == shellCommand.SCHEMA) {
|
|
441
|
+
printSchema();
|
|
416
442
|
} else {
|
|
417
443
|
printf("Error: Unknown command: \"%s\". Enter \":help\" for help\n", lineStr.c_str());
|
|
418
444
|
printf("Did you mean: \"%s\"?\n", findClosestCommand(lineStr).c_str());
|
|
@@ -533,6 +559,17 @@ std::vector<std::unique_ptr<QueryResult>> EmbeddedShell::processInput(std::strin
|
|
|
533
559
|
historyLine = input;
|
|
534
560
|
return queryResults;
|
|
535
561
|
}
|
|
562
|
+
// Normalize trailing semicolons
|
|
563
|
+
if (!unicodeInput.empty() && unicodeInput.back() == ';') {
|
|
564
|
+
// trim trailing ;
|
|
565
|
+
while (!unicodeInput.empty() && unicodeInput.back() == ';') {
|
|
566
|
+
unicodeInput.pop_back();
|
|
567
|
+
}
|
|
568
|
+
if (unicodeInput.empty()) {
|
|
569
|
+
return queryResults;
|
|
570
|
+
}
|
|
571
|
+
unicodeInput += ';';
|
|
572
|
+
}
|
|
536
573
|
// process shell commands
|
|
537
574
|
if (!continueLine && unicodeInput[0] == ':') {
|
|
538
575
|
processShellCommands(unicodeInput);
|
|
@@ -811,7 +848,6 @@ void EmbeddedShell::setComplete(const std::string& completeString) {
|
|
|
811
848
|
} else {
|
|
812
849
|
printf("Cannot parse '%s' to toggle completion highlighting. Expect 'on' or 'off'.\n",
|
|
813
850
|
completeStringLower.c_str());
|
|
814
|
-
return;
|
|
815
851
|
}
|
|
816
852
|
}
|
|
817
853
|
|
|
@@ -832,6 +868,7 @@ void EmbeddedShell::printHelp() {
|
|
|
832
868
|
printf("%s%s [on|off] %stoggle error highlighting on or off\n", TAB, shellCommand.ERRORS, TAB);
|
|
833
869
|
printf("%s%s [on|off] %stoggle completion highlighting on or off\n", TAB, shellCommand.COMPLETE,
|
|
834
870
|
TAB);
|
|
871
|
+
printf("%s%s %sprint database schema\n", TAB, shellCommand.SCHEMA, TAB);
|
|
835
872
|
printf("\n");
|
|
836
873
|
printf("%sNote: you can change and see several system configurations, such as num-threads, \n",
|
|
837
874
|
TAB);
|
|
@@ -1561,5 +1598,43 @@ void EmbeddedShell::printTruncatedExecutionResult(QueryResult& queryResult) cons
|
|
|
1561
1598
|
}
|
|
1562
1599
|
}
|
|
1563
1600
|
|
|
1601
|
+
void EmbeddedShell::printSchema() {
|
|
1602
|
+
std::stringstream ss;
|
|
1603
|
+
auto clientContext = conn->getClientContext();
|
|
1604
|
+
bool transactionStarted = false;
|
|
1605
|
+
if (transaction::Transaction::Get(*clientContext) == NULL) {
|
|
1606
|
+
transaction::TransactionContext::Get(*clientContext)
|
|
1607
|
+
->beginReadTransaction(); // start transaction to get schema
|
|
1608
|
+
transactionStarted = true;
|
|
1609
|
+
}
|
|
1610
|
+
auto extensionCypher = extension::ExtensionManager::Get(*clientContext)->toCypher();
|
|
1611
|
+
if (!extensionCypher.empty()) {
|
|
1612
|
+
ss << extensionCypher << std::endl;
|
|
1613
|
+
}
|
|
1614
|
+
const auto catalog = catalog::Catalog::Get(*clientContext);
|
|
1615
|
+
auto transaction = transaction::Transaction::Get(*clientContext);
|
|
1616
|
+
catalog::ToCypherInfo toCypherInfo;
|
|
1617
|
+
for (const auto& nodeTableEntry :
|
|
1618
|
+
catalog->getNodeTableEntries(transaction, false /* useInternal */)) {
|
|
1619
|
+
ss << nodeTableEntry->toCypher(toCypherInfo) << std::endl;
|
|
1620
|
+
}
|
|
1621
|
+
catalog::RelGroupToCypherInfo relTableToCypherInfo(clientContext);
|
|
1622
|
+
for (const auto& entry : catalog->getRelGroupEntries(transaction, false /* useInternal */)) {
|
|
1623
|
+
ss << entry->toCypher(relTableToCypherInfo) << std::endl;
|
|
1624
|
+
}
|
|
1625
|
+
catalog::RelGroupToCypherInfo relGroupToCypherInfo(clientContext);
|
|
1626
|
+
for (const auto sequenceEntry : catalog->getSequenceEntries(transaction)) {
|
|
1627
|
+
ss << sequenceEntry->toCypher(relGroupToCypherInfo) << std::endl;
|
|
1628
|
+
}
|
|
1629
|
+
for (auto macroName : catalog->getMacroNames(transaction)) {
|
|
1630
|
+
ss << catalog->getScalarMacroFunction(transaction, macroName)->toCypher(macroName)
|
|
1631
|
+
<< std::endl;
|
|
1632
|
+
}
|
|
1633
|
+
if (transactionStarted) {
|
|
1634
|
+
transaction::TransactionContext::Get(*clientContext)->commit();
|
|
1635
|
+
}
|
|
1636
|
+
printf("%s", ss.str().c_str());
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1564
1639
|
} // namespace main
|
|
1565
1640
|
} // namespace lbug
|
|
@@ -3306,7 +3306,7 @@ bool cypherComplete(const char* z) {
|
|
|
3306
3306
|
/* Token: */
|
|
3307
3307
|
/* State: ** SEMI WS OTHER */
|
|
3308
3308
|
/* 0 INVALID: */ {
|
|
3309
|
-
|
|
3309
|
+
2,
|
|
3310
3310
|
0,
|
|
3311
3311
|
2,
|
|
3312
3312
|
},
|
|
@@ -3553,8 +3553,8 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char* buf, size_t buflen,
|
|
|
3553
3553
|
// check if this forms a complete Cypher statement or not or if enter is pressed in
|
|
3554
3554
|
// the middle of a line
|
|
3555
3555
|
l.buf[l.len] = '\0';
|
|
3556
|
-
if (l.buf[0] != ':' &&
|
|
3557
|
-
|
|
3556
|
+
if (l.buf[0] != ':' && l.pos == l.len && !linenoiseAllWhitespace(l.buf) &&
|
|
3557
|
+
!cypherComplete(l.buf)) {
|
|
3558
3558
|
if (linenoiseEditInsertMulti(&l, "\r\n")) {
|
|
3559
3559
|
return -1;
|
|
3560
3560
|
}
|
|
@@ -289,6 +289,18 @@ def test_shell_auto_completion(temp_db) -> None:
|
|
|
289
289
|
assert test.shell_process.expect_exact(["(0 tuples)", pexpect.EOF]) == 0
|
|
290
290
|
|
|
291
291
|
|
|
292
|
+
def test_double_semicolon(temp_db) -> None:
|
|
293
|
+
test = (
|
|
294
|
+
ShellTest()
|
|
295
|
+
.add_argument(temp_db)
|
|
296
|
+
.statement("CREATE NODE TABLE User(name STRING, PRIMARY KEY(name));")
|
|
297
|
+
.statement("CREATE REL TABLE Follows(FROM User TO User, since INT64);")
|
|
298
|
+
.statement('MATCH (a:User)-[f:Follows]->(b:User) RETURN a.name, b.name, f.since;;')
|
|
299
|
+
)
|
|
300
|
+
result = test.run()
|
|
301
|
+
result.check_stdout("(0 tuples)")
|
|
302
|
+
|
|
303
|
+
|
|
292
304
|
def test_shell_unicode_input(temp_db) -> None:
|
|
293
305
|
test = (
|
|
294
306
|
ShellTest()
|
|
@@ -18,6 +18,7 @@ def test_help(temp_db) -> None:
|
|
|
18
18
|
" :highlight [on|off] toggle syntax highlighting on or off",
|
|
19
19
|
" :render_errors [on|off] toggle error highlighting on or off",
|
|
20
20
|
" :render_completion [on|off] toggle completion highlighting on or off",
|
|
21
|
+
" :schema print database schema",
|
|
21
22
|
"",
|
|
22
23
|
" Note: you can change and see several system configurations, such as num-threads, ",
|
|
23
24
|
" timeout, and progress_bar using Cypher CALL statements.",
|
|
@@ -636,6 +637,24 @@ def test_completion_highlighting(temp_db) -> None:
|
|
|
636
637
|
)
|
|
637
638
|
|
|
638
639
|
|
|
640
|
+
def test_schema_with_tables(temp_db) -> None:
|
|
641
|
+
test = (
|
|
642
|
+
ShellTest()
|
|
643
|
+
.add_argument(temp_db)
|
|
644
|
+
.statement("CREATE NODE TABLE User(name STRING, age INT64, PRIMARY KEY (name));")
|
|
645
|
+
.statement("CREATE NODE TABLE City(name STRING, population INT64, PRIMARY KEY (name));")
|
|
646
|
+
.statement("CREATE REL TABLE Follows(FROM User TO User, since INT64);")
|
|
647
|
+
.statement("CREATE REL TABLE LivesIn(FROM User TO City);")
|
|
648
|
+
.statement(":schema")
|
|
649
|
+
)
|
|
650
|
+
result = test.run()
|
|
651
|
+
# Check that the schema output includes the created tables
|
|
652
|
+
result.check_stdout("CREATE NODE TABLE `User` (`name` STRING,`age` INT64, PRIMARY KEY(`name`));")
|
|
653
|
+
result.check_stdout("CREATE NODE TABLE `City` (`name` STRING,`population` INT64, PRIMARY KEY(`name`));")
|
|
654
|
+
result.check_stdout("CREATE REL TABLE `Follows` (FROM `User` TO `User`, `since` INT64,MANY_MANY);")
|
|
655
|
+
result.check_stdout("CREATE REL TABLE `LivesIn` (FROM `User` TO `City`, MANY_MANY);")
|
|
656
|
+
|
|
657
|
+
|
|
639
658
|
def test_bad_command(temp_db) -> None:
|
|
640
659
|
test = (
|
|
641
660
|
ShellTest()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lbug",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1-dev.1",
|
|
4
4
|
"description": "An in-process property graph database management system built for query speed and scalability.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "./index.mjs",
|
|
@@ -12,17 +12,24 @@
|
|
|
12
12
|
"types": "./lbug.d.ts"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
+
"files": [
|
|
16
|
+
"index.js",
|
|
17
|
+
"index.mjs",
|
|
18
|
+
"lbug.d.ts",
|
|
19
|
+
"lbugjs.node"
|
|
20
|
+
],
|
|
15
21
|
"type": "commonjs",
|
|
16
22
|
"homepage": "https://ladybugdb.com/",
|
|
17
23
|
"repository": {
|
|
18
24
|
"type": "git",
|
|
19
|
-
"url": "https://github.com/LadybugDB/ladybug"
|
|
25
|
+
"url": "git+https://github.com/LadybugDB/ladybug.git"
|
|
20
26
|
},
|
|
21
27
|
"scripts": {
|
|
22
28
|
"test": "mocha test --timeout 20000",
|
|
23
29
|
"clean": "node clean.js",
|
|
24
30
|
"clean-all": "node clean.js all",
|
|
25
31
|
"build": "node build.js",
|
|
32
|
+
"prepublishOnly": "npm run build",
|
|
26
33
|
"install": "node install.js"
|
|
27
34
|
},
|
|
28
35
|
"author": "Ladybug Team",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|