duckdb 0.5.2-dev1740.0 → 0.5.2-dev1745.0
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/binding.gyp +6 -0
- package/package.json +1 -1
- package/src/duckdb.cpp +66 -32
- package/src/duckdb.hpp +60 -13
- package/src/parquet-amalgamation.cpp +37625 -37625
package/binding.gyp
CHANGED
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -48711,6 +48711,8 @@ class DatabaseInstance;
|
|
|
48711
48711
|
enum class ErrorType : uint16_t {
|
|
48712
48712
|
// error message types
|
|
48713
48713
|
UNSIGNED_EXTENSION = 0,
|
|
48714
|
+
INVALIDATED_TRANSACTION = 1,
|
|
48715
|
+
INVALIDATED_DATABASE = 2,
|
|
48714
48716
|
|
|
48715
48717
|
// this should always be the last value
|
|
48716
48718
|
ERROR_COUNT,
|
|
@@ -48736,13 +48738,18 @@ public:
|
|
|
48736
48738
|
return FormatExceptionRecursive(error_type, values, params...);
|
|
48737
48739
|
}
|
|
48738
48740
|
|
|
48741
|
+
template <typename... Args>
|
|
48742
|
+
static string FormatException(ClientContext &context, ErrorType error_type, Args... params) {
|
|
48743
|
+
return Get(context).FormatException(error_type, params...);
|
|
48744
|
+
}
|
|
48745
|
+
|
|
48739
48746
|
DUCKDB_API static string InvalidUnicodeError(const string &input, const string &context);
|
|
48740
48747
|
|
|
48741
48748
|
//! Adds a custom error for a specific error type
|
|
48742
48749
|
void AddCustomError(ErrorType type, string new_error);
|
|
48743
48750
|
|
|
48744
|
-
DUCKDB_API ErrorManager &Get(ClientContext &context);
|
|
48745
|
-
DUCKDB_API ErrorManager &Get(DatabaseInstance &context);
|
|
48751
|
+
DUCKDB_API static ErrorManager &Get(ClientContext &context);
|
|
48752
|
+
DUCKDB_API static ErrorManager &Get(DatabaseInstance &context);
|
|
48746
48753
|
|
|
48747
48754
|
private:
|
|
48748
48755
|
map<ErrorType, string> custom_errors;
|
|
@@ -133571,6 +133578,7 @@ public:
|
|
|
133571
133578
|
|
|
133572
133579
|
|
|
133573
133580
|
|
|
133581
|
+
|
|
133574
133582
|
namespace duckdb {
|
|
133575
133583
|
|
|
133576
133584
|
struct ActiveQueryContext {
|
|
@@ -133639,7 +133647,7 @@ unique_ptr<DataChunk> ClientContext::FetchInternal(ClientContextLock &lock, Exec
|
|
|
133639
133647
|
// fatal exceptions invalidate the entire database
|
|
133640
133648
|
result.SetError(PreservedError(ex));
|
|
133641
133649
|
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
133642
|
-
db.
|
|
133650
|
+
ValidChecker::Invalidate(db, ex.what());
|
|
133643
133651
|
} catch (const Exception &ex) {
|
|
133644
133652
|
result.SetError(PreservedError(ex));
|
|
133645
133653
|
} catch (std::exception &ex) {
|
|
@@ -133655,12 +133663,13 @@ void ClientContext::BeginTransactionInternal(ClientContextLock &lock, bool requi
|
|
|
133655
133663
|
// check if we are on AutoCommit. In this case we should start a transaction
|
|
133656
133664
|
D_ASSERT(!active_query);
|
|
133657
133665
|
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
133658
|
-
if (
|
|
133659
|
-
throw FatalException(
|
|
133666
|
+
if (ValidChecker::IsInvalidated(db)) {
|
|
133667
|
+
throw FatalException(ErrorManager::FormatException(*this, ErrorType::INVALIDATED_DATABASE,
|
|
133668
|
+
ValidChecker::InvalidatedMessage(db)));
|
|
133660
133669
|
}
|
|
133661
133670
|
if (requires_valid_transaction && transaction.HasActiveTransaction() &&
|
|
133662
|
-
transaction.ActiveTransaction()
|
|
133663
|
-
throw Exception(
|
|
133671
|
+
ValidChecker::IsInvalidated(transaction.ActiveTransaction())) {
|
|
133672
|
+
throw Exception(ErrorManager::FormatException(*this, ErrorType::INVALIDATED_TRANSACTION));
|
|
133664
133673
|
}
|
|
133665
133674
|
active_query = make_unique<ActiveQueryContext>();
|
|
133666
133675
|
if (transaction.IsAutoCommit()) {
|
|
@@ -133703,12 +133712,12 @@ PreservedError ClientContext::EndQueryInternal(ClientContextLock &lock, bool suc
|
|
|
133703
133712
|
}
|
|
133704
133713
|
} else if (invalidate_transaction) {
|
|
133705
133714
|
D_ASSERT(!success);
|
|
133706
|
-
ActiveTransaction()
|
|
133715
|
+
ValidChecker::Invalidate(ActiveTransaction(), "Failed to commit");
|
|
133707
133716
|
}
|
|
133708
133717
|
}
|
|
133709
133718
|
} catch (FatalException &ex) {
|
|
133710
133719
|
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
133711
|
-
db.
|
|
133720
|
+
ValidChecker::Invalidate(db, ex.what());
|
|
133712
133721
|
error = PreservedError(ex);
|
|
133713
133722
|
} catch (const Exception &ex) {
|
|
133714
133723
|
error = PreservedError(ex);
|
|
@@ -133887,8 +133896,8 @@ unique_ptr<PendingQueryResult> ClientContext::PendingPreparedStatement(ClientCon
|
|
|
133887
133896
|
PendingQueryParameters parameters) {
|
|
133888
133897
|
D_ASSERT(active_query);
|
|
133889
133898
|
auto &statement = *statement_p;
|
|
133890
|
-
if (ActiveTransaction()
|
|
133891
|
-
throw Exception(
|
|
133899
|
+
if (ValidChecker::IsInvalidated(ActiveTransaction()) && statement.properties.requires_valid_transaction) {
|
|
133900
|
+
throw Exception(ErrorManager::FormatException(*this, ErrorType::INVALIDATED_TRANSACTION));
|
|
133892
133901
|
}
|
|
133893
133902
|
auto &db_config = DBConfig::GetConfig(*this);
|
|
133894
133903
|
if (db_config.options.access_mode == AccessMode::READ_ONLY && !statement.properties.read_only) {
|
|
@@ -133942,7 +133951,7 @@ PendingExecutionResult ClientContext::ExecuteTaskInternal(ClientContextLock &loc
|
|
|
133942
133951
|
// fatal exceptions invalidate the entire database
|
|
133943
133952
|
result.SetError(PreservedError(ex));
|
|
133944
133953
|
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
133945
|
-
db.
|
|
133954
|
+
ValidChecker::Invalidate(db, ex.what());
|
|
133946
133955
|
} catch (const Exception &ex) {
|
|
133947
133956
|
result.SetError(PreservedError(ex));
|
|
133948
133957
|
} catch (std::exception &ex) {
|
|
@@ -134196,7 +134205,7 @@ unique_ptr<PendingQueryResult> ClientContext::PendingStatementOrPreparedStatemen
|
|
|
134196
134205
|
} catch (FatalException &ex) {
|
|
134197
134206
|
// fatal exceptions invalidate the entire database
|
|
134198
134207
|
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
134199
|
-
db.
|
|
134208
|
+
ValidChecker::Invalidate(db, ex.what());
|
|
134200
134209
|
result = make_unique<PendingQueryResult>(PreservedError(ex));
|
|
134201
134210
|
return result;
|
|
134202
134211
|
} catch (const Exception &ex) {
|
|
@@ -134229,9 +134238,9 @@ unique_ptr<PendingQueryResult> ClientContext::PendingStatementOrPreparedStatemen
|
|
|
134229
134238
|
invalidate_query = false;
|
|
134230
134239
|
} catch (FatalException &ex) {
|
|
134231
134240
|
// fatal exceptions invalidate the entire database
|
|
134232
|
-
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
134233
134241
|
if (!config.query_verification_enabled) {
|
|
134234
|
-
db
|
|
134242
|
+
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
134243
|
+
ValidChecker::Invalidate(db, ex.what());
|
|
134235
134244
|
}
|
|
134236
134245
|
result = make_unique<PendingQueryResult>(PreservedError(ex));
|
|
134237
134246
|
} catch (const Exception &ex) {
|
|
@@ -134418,8 +134427,8 @@ void ClientContext::RegisterFunction(CreateFunctionInfo *info) {
|
|
|
134418
134427
|
void ClientContext::RunFunctionInTransactionInternal(ClientContextLock &lock, const std::function<void(void)> &fun,
|
|
134419
134428
|
bool requires_valid_transaction) {
|
|
134420
134429
|
if (requires_valid_transaction && transaction.HasActiveTransaction() &&
|
|
134421
|
-
|
|
134422
|
-
throw Exception(
|
|
134430
|
+
ValidChecker::IsInvalidated(ActiveTransaction())) {
|
|
134431
|
+
throw Exception(ErrorManager::FormatException(*this, ErrorType::INVALIDATED_TRANSACTION));
|
|
134423
134432
|
}
|
|
134424
134433
|
// check if we are on AutoCommit. In this case we should start a transaction
|
|
134425
134434
|
bool require_new_transaction = transaction.IsAutoCommit() && !transaction.HasActiveTransaction();
|
|
@@ -134436,13 +134445,13 @@ void ClientContext::RunFunctionInTransactionInternal(ClientContextLock &lock, co
|
|
|
134436
134445
|
throw;
|
|
134437
134446
|
} catch (FatalException &ex) {
|
|
134438
134447
|
auto &db = DatabaseInstance::GetDatabase(*this);
|
|
134439
|
-
db.
|
|
134448
|
+
ValidChecker::Invalidate(db, ex.what());
|
|
134440
134449
|
throw;
|
|
134441
134450
|
} catch (std::exception &ex) {
|
|
134442
134451
|
if (require_new_transaction) {
|
|
134443
134452
|
transaction.Rollback();
|
|
134444
134453
|
} else {
|
|
134445
|
-
ActiveTransaction().
|
|
134454
|
+
ValidChecker::Invalidate(ActiveTransaction(), ex.what());
|
|
134446
134455
|
}
|
|
134447
134456
|
throw;
|
|
134448
134457
|
}
|
|
@@ -134806,7 +134815,7 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string
|
|
|
134806
134815
|
statement_verifiers.push_back(move(prepared_statement_verifier));
|
|
134807
134816
|
}
|
|
134808
134817
|
} else {
|
|
134809
|
-
if (
|
|
134818
|
+
if (ValidChecker::IsInvalidated(*db)) {
|
|
134810
134819
|
return original->materialized_result->GetErrorObject();
|
|
134811
134820
|
}
|
|
134812
134821
|
}
|
|
@@ -135973,7 +135982,7 @@ DBConfig::DBConfig(std::unordered_map<string, string> &config_dict, bool read_on
|
|
|
135973
135982
|
DBConfig::~DBConfig() {
|
|
135974
135983
|
}
|
|
135975
135984
|
|
|
135976
|
-
DatabaseInstance::DatabaseInstance()
|
|
135985
|
+
DatabaseInstance::DatabaseInstance() {
|
|
135977
135986
|
}
|
|
135978
135987
|
|
|
135979
135988
|
DatabaseInstance::~DatabaseInstance() {
|
|
@@ -136198,6 +136207,9 @@ void DatabaseInstance::Configure(DBConfig &new_config) {
|
|
|
136198
136207
|
config.replacement_opens = move(new_config.replacement_opens);
|
|
136199
136208
|
config.parser_extensions = move(new_config.parser_extensions);
|
|
136200
136209
|
config.error_manager = move(new_config.error_manager);
|
|
136210
|
+
if (!config.error_manager) {
|
|
136211
|
+
config.error_manager = make_unique<ErrorManager>();
|
|
136212
|
+
}
|
|
136201
136213
|
}
|
|
136202
136214
|
|
|
136203
136215
|
DBConfig &DBConfig::GetConfig(ClientContext &context) {
|
|
@@ -136250,11 +136262,12 @@ string ClientConfig::ExtractTimezone() const {
|
|
|
136250
136262
|
}
|
|
136251
136263
|
}
|
|
136252
136264
|
|
|
136253
|
-
|
|
136254
|
-
|
|
136265
|
+
ValidChecker &DatabaseInstance::GetValidChecker() {
|
|
136266
|
+
return db_validity;
|
|
136255
136267
|
}
|
|
136256
|
-
|
|
136257
|
-
|
|
136268
|
+
|
|
136269
|
+
ValidChecker &ValidChecker::Get(DatabaseInstance &db) {
|
|
136270
|
+
return db.GetValidChecker();
|
|
136258
136271
|
}
|
|
136259
136272
|
|
|
136260
136273
|
} // namespace duckdb
|
|
@@ -136364,6 +136377,9 @@ static DefaultError internal_errors[] = {
|
|
|
136364
136377
|
{ErrorType::UNSIGNED_EXTENSION,
|
|
136365
136378
|
"Extension \"%s\" could not be loaded because its signature is either missing or invalid and unsigned extensions "
|
|
136366
136379
|
"are disabled by configuration (allow_unsigned_extensions)"},
|
|
136380
|
+
{ErrorType::INVALIDATED_TRANSACTION, "Current transaction is aborted (please ROLLBACK)"},
|
|
136381
|
+
{ErrorType::INVALIDATED_DATABASE, "Failed: database has been invalidated because of a previous fatal error. The "
|
|
136382
|
+
"database must be restarted prior to being used again.\nOriginal error: \"%s\""},
|
|
136367
136383
|
{ErrorType::INVALID, nullptr}};
|
|
136368
136384
|
|
|
136369
136385
|
string ErrorManager::FormatExceptionRecursive(ErrorType error_type, vector<ExceptionFormatValue> &values) {
|
|
@@ -149884,6 +149900,28 @@ void StreamQueryResult::Close() {
|
|
|
149884
149900
|
} // namespace duckdb
|
|
149885
149901
|
|
|
149886
149902
|
|
|
149903
|
+
namespace duckdb {
|
|
149904
|
+
|
|
149905
|
+
ValidChecker::ValidChecker() : is_invalidated(false) {
|
|
149906
|
+
}
|
|
149907
|
+
|
|
149908
|
+
void ValidChecker::Invalidate(string error) {
|
|
149909
|
+
lock_guard<mutex> l(invalidate_lock);
|
|
149910
|
+
this->is_invalidated = true;
|
|
149911
|
+
this->invalidated_msg = move(error);
|
|
149912
|
+
}
|
|
149913
|
+
|
|
149914
|
+
bool ValidChecker::IsInvalidated() {
|
|
149915
|
+
return this->is_invalidated;
|
|
149916
|
+
}
|
|
149917
|
+
|
|
149918
|
+
string ValidChecker::InvalidatedMessage() {
|
|
149919
|
+
lock_guard<mutex> l(invalidate_lock);
|
|
149920
|
+
return invalidated_msg;
|
|
149921
|
+
}
|
|
149922
|
+
} // namespace duckdb
|
|
149923
|
+
|
|
149924
|
+
|
|
149887
149925
|
//===----------------------------------------------------------------------===//
|
|
149888
149926
|
// DuckDB
|
|
149889
149927
|
//
|
|
@@ -221497,8 +221535,7 @@ Transaction::Transaction(weak_ptr<ClientContext> context_p, transaction_t start_
|
|
|
221497
221535
|
timestamp_t start_timestamp, idx_t catalog_version)
|
|
221498
221536
|
: context(move(context_p)), start_time(start_time), transaction_id(transaction_id), commit_id(0),
|
|
221499
221537
|
highest_active_query(0), active_query(MAXIMUM_QUERY_ID), start_timestamp(start_timestamp),
|
|
221500
|
-
catalog_version(catalog_version),
|
|
221501
|
-
storage(make_unique<LocalStorage>(*this)) {
|
|
221538
|
+
catalog_version(catalog_version), undo_buffer(context.lock()), storage(make_unique<LocalStorage>(*this)) {
|
|
221502
221539
|
}
|
|
221503
221540
|
|
|
221504
221541
|
Transaction::~Transaction() {
|
|
@@ -221605,11 +221642,8 @@ void Transaction::Cleanup() {
|
|
|
221605
221642
|
undo_buffer.Cleanup();
|
|
221606
221643
|
}
|
|
221607
221644
|
|
|
221608
|
-
|
|
221609
|
-
|
|
221610
|
-
}
|
|
221611
|
-
bool Transaction::IsInvalidated() {
|
|
221612
|
-
return is_invalidated;
|
|
221645
|
+
ValidChecker &ValidChecker::Get(Transaction &transaction) {
|
|
221646
|
+
return transaction.transaction_validity;
|
|
221613
221647
|
}
|
|
221614
221648
|
|
|
221615
221649
|
} // namespace duckdb
|
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "v0.5.2-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "08c5167e04"
|
|
15
|
+
#define DUCKDB_VERSION "v0.5.2-dev1745"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|
|
@@ -14703,6 +14703,58 @@ struct TransactionData {
|
|
|
14703
14703
|
|
|
14704
14704
|
} // namespace duckdb
|
|
14705
14705
|
|
|
14706
|
+
//===----------------------------------------------------------------------===//
|
|
14707
|
+
// DuckDB
|
|
14708
|
+
//
|
|
14709
|
+
// duckdb/main/valid_checker.hpp
|
|
14710
|
+
//
|
|
14711
|
+
//
|
|
14712
|
+
//===----------------------------------------------------------------------===//
|
|
14713
|
+
|
|
14714
|
+
|
|
14715
|
+
|
|
14716
|
+
|
|
14717
|
+
|
|
14718
|
+
|
|
14719
|
+
|
|
14720
|
+
namespace duckdb {
|
|
14721
|
+
class DatabaseInstance;
|
|
14722
|
+
class Transaction;
|
|
14723
|
+
|
|
14724
|
+
class ValidChecker {
|
|
14725
|
+
public:
|
|
14726
|
+
ValidChecker();
|
|
14727
|
+
|
|
14728
|
+
DUCKDB_API static ValidChecker &Get(DatabaseInstance &db);
|
|
14729
|
+
DUCKDB_API static ValidChecker &Get(Transaction &transaction);
|
|
14730
|
+
|
|
14731
|
+
DUCKDB_API void Invalidate(string error);
|
|
14732
|
+
DUCKDB_API bool IsInvalidated();
|
|
14733
|
+
DUCKDB_API string InvalidatedMessage();
|
|
14734
|
+
|
|
14735
|
+
template <class T>
|
|
14736
|
+
static bool IsInvalidated(T &o) {
|
|
14737
|
+
return Get(o).IsInvalidated();
|
|
14738
|
+
}
|
|
14739
|
+
template <class T>
|
|
14740
|
+
static void Invalidate(T &o, string error) {
|
|
14741
|
+
Get(o).Invalidate(move(error));
|
|
14742
|
+
}
|
|
14743
|
+
|
|
14744
|
+
template <class T>
|
|
14745
|
+
static string InvalidatedMessage(T &o) {
|
|
14746
|
+
return Get(o).InvalidatedMessage();
|
|
14747
|
+
}
|
|
14748
|
+
|
|
14749
|
+
private:
|
|
14750
|
+
//! Set to true if a fatal exception has occurred
|
|
14751
|
+
mutex invalidate_lock;
|
|
14752
|
+
atomic<bool> is_invalidated;
|
|
14753
|
+
string invalidated_msg;
|
|
14754
|
+
};
|
|
14755
|
+
|
|
14756
|
+
} // namespace duckdb
|
|
14757
|
+
|
|
14706
14758
|
|
|
14707
14759
|
namespace duckdb {
|
|
14708
14760
|
class SequenceCatalogEntry;
|
|
@@ -14722,7 +14774,6 @@ struct UpdateInfo;
|
|
|
14722
14774
|
|
|
14723
14775
|
//! The transaction object holds information about a currently running or past
|
|
14724
14776
|
//! transaction
|
|
14725
|
-
|
|
14726
14777
|
class Transaction {
|
|
14727
14778
|
public:
|
|
14728
14779
|
Transaction(weak_ptr<ClientContext> context, transaction_t start_time, transaction_t transaction_id,
|
|
@@ -14747,8 +14798,8 @@ public:
|
|
|
14747
14798
|
idx_t catalog_version;
|
|
14748
14799
|
//! Map of all sequences that were used during the transaction and the value they had in this transaction
|
|
14749
14800
|
unordered_map<SequenceCatalogEntry *, SequenceValue> sequence_usage;
|
|
14750
|
-
//!
|
|
14751
|
-
|
|
14801
|
+
//! The validity checker of the transaction
|
|
14802
|
+
ValidChecker transaction_validity;
|
|
14752
14803
|
|
|
14753
14804
|
public:
|
|
14754
14805
|
static Transaction &GetTransaction(ClientContext &context);
|
|
@@ -14767,8 +14818,6 @@ public:
|
|
|
14767
14818
|
//! Cleanup the undo buffer
|
|
14768
14819
|
void Cleanup();
|
|
14769
14820
|
|
|
14770
|
-
void Invalidate();
|
|
14771
|
-
bool IsInvalidated();
|
|
14772
14821
|
bool ChangesMade();
|
|
14773
14822
|
|
|
14774
14823
|
timestamp_t GetCurrentTransactionStartTimestamp() {
|
|
@@ -15983,8 +16032,6 @@ private:
|
|
|
15983
16032
|
|
|
15984
16033
|
|
|
15985
16034
|
|
|
15986
|
-
|
|
15987
|
-
|
|
15988
16035
|
//===----------------------------------------------------------------------===//
|
|
15989
16036
|
// DuckDB
|
|
15990
16037
|
//
|
|
@@ -16624,6 +16671,8 @@ private:
|
|
|
16624
16671
|
|
|
16625
16672
|
} // namespace duckdb
|
|
16626
16673
|
|
|
16674
|
+
|
|
16675
|
+
|
|
16627
16676
|
//===----------------------------------------------------------------------===//
|
|
16628
16677
|
// DuckDB
|
|
16629
16678
|
//
|
|
@@ -16678,8 +16727,7 @@ public:
|
|
|
16678
16727
|
DUCKDB_API TaskScheduler &GetScheduler();
|
|
16679
16728
|
DUCKDB_API ObjectCache &GetObjectCache();
|
|
16680
16729
|
DUCKDB_API ConnectionManager &GetConnectionManager();
|
|
16681
|
-
DUCKDB_API
|
|
16682
|
-
DUCKDB_API bool IsInvalidated();
|
|
16730
|
+
DUCKDB_API ValidChecker &GetValidChecker();
|
|
16683
16731
|
DUCKDB_API void SetExtensionLoaded(const std::string &extension_name);
|
|
16684
16732
|
|
|
16685
16733
|
idx_t NumberOfThreads();
|
|
@@ -16703,8 +16751,7 @@ private:
|
|
|
16703
16751
|
unique_ptr<ObjectCache> object_cache;
|
|
16704
16752
|
unique_ptr<ConnectionManager> connection_manager;
|
|
16705
16753
|
unordered_set<std::string> loaded_extensions;
|
|
16706
|
-
|
|
16707
|
-
atomic<bool> is_invalidated;
|
|
16754
|
+
ValidChecker db_validity;
|
|
16708
16755
|
};
|
|
16709
16756
|
|
|
16710
16757
|
//! The database object. This object holds the catalog and all the
|