should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,100 @@
//===----------------------------------------------------------------------===//
//
// DuckDB
//
// arrow/arrow_test_helper.hpp
//
//
//===----------------------------------------------------------------------===//
#pragma once
#include <utility>
#include "test_helpers.hpp"
#include "duckdb/common/helper.hpp"
#include "duckdb/common/types/value.hpp"
#include "duckdb/common/vector.hpp"
#include "duckdb/main/connection.hpp"
#include "duckdb/main/client_config.hpp"
#include "duckdb/main/database.hpp"
#include "duckdb/function/table/arrow.hpp"
#include "duckdb/common/arrow/arrow_appender.hpp"
#include "duckdb/common/arrow/arrow_converter.hpp"
#include "duckdb/common/arrow/arrow_wrapper.hpp"
#include "duckdb/main/extension_helper.hpp"
#include "duckdb/common/arrow/arrow_query_result.hpp"
class ArrowStreamTestFactory {
public:
static duckdb::unique_ptr<duckdb::ArrowArrayStreamWrapper> CreateStream(uintptr_t this_ptr,
duckdb::ArrowStreamParameters &parameters);
static void GetSchema(ArrowArrayStream *arrow_array_stream, ArrowSchema &schema);
};
namespace duckdb {
class ArrowTestFactory {
public:
ArrowTestFactory(vector<LogicalType> types_p, vector<string> names_p, duckdb::unique_ptr<QueryResult> result_p,
bool big_result, ClientProperties options, ClientContext &context)
: types(std::move(types_p)), names(std::move(names_p)), result(std::move(result_p)), big_result(big_result),
options(std::move(options)), context(context) {
if (result->type == QueryResultType::ARROW_RESULT) {
auto &arrow_result = result->Cast<ArrowQueryResult>();
prefetched_chunks = arrow_result.ConsumeArrays();
chunk_iterator = prefetched_chunks.begin();
}
}
vector<LogicalType> types;
vector<string> names;
duckdb::unique_ptr<QueryResult> result;
vector<unique_ptr<ArrowArrayWrapper>> prefetched_chunks;
vector<unique_ptr<ArrowArrayWrapper>>::iterator chunk_iterator;
bool big_result;
ClientProperties options;
ClientContext &context;
struct ArrowArrayStreamData {
explicit ArrowArrayStreamData(ArrowTestFactory &factory, ClientProperties options)
: factory(factory), options(options) {
}
ArrowTestFactory &factory;
ClientProperties options;
};
static int ArrowArrayStreamGetSchema(struct ArrowArrayStream *stream, struct ArrowSchema *out);
static int ArrowArrayStreamGetNext(struct ArrowArrayStream *stream, struct ArrowArray *out);
static const char *ArrowArrayStreamGetLastError(struct ArrowArrayStream *stream);
static void ArrowArrayStreamRelease(struct ArrowArrayStream *stream);
static duckdb::unique_ptr<duckdb::ArrowArrayStreamWrapper> CreateStream(uintptr_t this_ptr,
ArrowStreamParameters &parameters);
static void GetSchema(ArrowArrayStream *, ArrowSchema &schema);
void ToArrowSchema(struct ArrowSchema *out);
};
class ArrowTestHelper {
public:
//! Used in the Arrow Roundtrip Tests
static bool RunArrowComparison(Connection &con, const string &query, bool big_result = false);
//! Used in the ADBC Testing
static bool RunArrowComparison(Connection &con, const string &query, ArrowArrayStream &arrow_stream);
private:
static bool CompareResults(Connection &con, unique_ptr<QueryResult> arrow, unique_ptr<MaterializedQueryResult> duck,
const string &query);
public:
static unique_ptr<QueryResult> ScanArrowObject(Connection &con, vector<Value> &params);
static vector<Value> ConstructArrowScan(ArrowTestFactory &factory);
static vector<Value> ConstructArrowScan(ArrowArrayStream &stream);
};
} // namespace duckdb

View File

@@ -0,0 +1,344 @@
//===----------------------------------------------------------------------===//
//
// DuckDB
//
// capi_tester.hpp
//
//
//===----------------------------------------------------------------------===//
#pragma once
#include "catch.hpp"
#include "duckdb.h"
#include "test_helpers.hpp"
#include "duckdb/common/arrow/arrow.hpp"
#include "duckdb/common/exception.hpp"
namespace duckdb {
class CAPIDataChunk {
public:
CAPIDataChunk(duckdb_data_chunk chunk_p) : chunk(chunk_p) {
}
~CAPIDataChunk() {
duckdb_destroy_data_chunk(&chunk);
}
idx_t ColumnCount() {
return duckdb_data_chunk_get_column_count(chunk);
}
idx_t size() {
return duckdb_data_chunk_get_size(chunk);
}
duckdb_vector GetVector(idx_t col) {
return duckdb_data_chunk_get_vector(chunk, col);
}
void *GetData(idx_t col) {
return duckdb_vector_get_data(GetVector(col));
}
uint64_t *GetValidity(idx_t col) {
return duckdb_vector_get_validity(GetVector(col));
}
duckdb_vector GetListChildVector(idx_t col) {
return duckdb_list_vector_get_child(GetVector(col));
}
void *GetListChildData(idx_t col) {
return duckdb_vector_get_data(GetListChildVector(col));
}
duckdb_vector GetStructChildVector(idx_t col, idx_t idx) {
return duckdb_struct_vector_get_child(GetVector(col), idx);
}
void *GetStructChildData(idx_t col, idx_t idx) {
return duckdb_vector_get_data(GetStructChildVector(col, idx));
}
duckdb_vector GetArrayChildVector(idx_t col) {
return duckdb_array_vector_get_child(GetVector(col));
}
void *GetArrayChildData(idx_t col) {
return duckdb_vector_get_data(GetArrayChildVector(col));
}
duckdb_data_chunk GetChunk() {
return chunk;
}
private:
duckdb_data_chunk chunk;
};
class CAPIResult {
public:
CAPIResult() {
}
CAPIResult(duckdb_result result, bool success) : success(success), result(result) {
}
~CAPIResult() {
duckdb_destroy_result(&result);
}
public:
bool HasError() const {
return !success;
}
void Query(duckdb_connection connection, string query) {
success = (duckdb_query(connection, query.c_str(), &result) == DuckDBSuccess);
if (!success) {
REQUIRE(ErrorMessage() != nullptr);
REQUIRE(ErrorType() != DUCKDB_ERROR_INVALID);
}
}
void QueryPrepared(duckdb_prepared_statement statement) {
success = duckdb_execute_prepared(statement, &result) == DuckDBSuccess;
if (!success) {
REQUIRE(ErrorMessage() != nullptr);
REQUIRE(ErrorType() != DUCKDB_ERROR_INVALID);
}
}
duckdb_type ColumnType(idx_t col) {
return duckdb_column_type(&result, col);
}
idx_t ChunkCount() {
return duckdb_result_chunk_count(result);
}
unique_ptr<CAPIDataChunk> StreamChunk() {
auto chunk = duckdb_stream_fetch_chunk(result);
if (!chunk) {
return nullptr;
}
return make_uniq<CAPIDataChunk>(chunk);
}
bool IsStreaming() {
return duckdb_result_is_streaming(result);
}
unique_ptr<CAPIDataChunk> FetchChunk(idx_t chunk_idx) {
auto chunk = duckdb_result_get_chunk(result, chunk_idx);
if (!chunk) {
return nullptr;
}
return make_uniq<CAPIDataChunk>(chunk);
}
unique_ptr<CAPIDataChunk> NextChunk() {
auto chunk = duckdb_fetch_chunk(result);
if (!chunk) {
return nullptr;
}
return make_uniq<CAPIDataChunk>(chunk);
}
template <class T>
T *ColumnData(idx_t col) {
return (T *)duckdb_column_data(&result, col);
}
idx_t ColumnCount() {
return duckdb_column_count(&result);
}
idx_t row_count() {
return duckdb_row_count(&result);
}
idx_t rows_changed() {
return duckdb_rows_changed(&result);
}
template <class T>
T Fetch(idx_t col, idx_t row) {
throw NotImplementedException("Unimplemented type for fetch");
}
bool IsNull(idx_t col, idx_t row) {
auto nullmask_ptr = duckdb_nullmask_data(&result, col);
REQUIRE(duckdb_value_is_null(&result, col, row) == nullmask_ptr[row]);
return nullmask_ptr[row];
}
const char *ErrorMessage() {
return duckdb_result_error(&result);
}
duckdb_error_type ErrorType() {
return duckdb_result_error_type(&result);
}
string ColumnName(idx_t col) {
auto colname = duckdb_column_name(&result, col);
return colname ? string(colname) : string();
}
duckdb_result &InternalResult() {
return result;
}
public:
bool success = false;
protected:
duckdb_result result;
};
template <>
bool CAPIResult::Fetch(idx_t col, idx_t row);
template <>
int8_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
int16_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
int32_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
int64_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
uint8_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
uint16_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
uint32_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
uint64_t CAPIResult::Fetch(idx_t col, idx_t row);
template <>
float CAPIResult::Fetch(idx_t col, idx_t row);
template <>
double CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_decimal CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_date CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_time CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_time_ns CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_timestamp CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_timestamp_s CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_timestamp_ms CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_timestamp_ns CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_interval CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_blob CAPIResult::Fetch(idx_t col, idx_t row);
template <>
string CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_date_struct CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_time_struct CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_timestamp_struct CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_hugeint CAPIResult::Fetch(idx_t col, idx_t row);
template <>
duckdb_uhugeint CAPIResult::Fetch(idx_t col, idx_t row);
class CAPITester {
public:
CAPITester() : database(nullptr), connection(nullptr) {
}
~CAPITester() {
Cleanup();
}
void Cleanup() {
if (connection) {
duckdb_disconnect(&connection);
connection = nullptr;
}
if (database) {
duckdb_close(&database);
database = nullptr;
}
}
bool OpenDatabase(const char *path) {
Cleanup();
if (duckdb_open(path, &database) != DuckDBSuccess) {
return false;
}
return duckdb_connect(database, &connection) == DuckDBSuccess;
}
bool ChangeConnection() {
duckdb_disconnect(&connection);
return duckdb_connect(database, &connection) == DuckDBSuccess;
}
duckdb::unique_ptr<CAPIResult> Query(string query) {
D_ASSERT(connection);
auto result = make_uniq<CAPIResult>();
result->Query(connection, query);
return result;
}
duckdb::unique_ptr<CAPIResult> QueryPrepared(duckdb_prepared_statement prepared) {
D_ASSERT(connection);
auto result = make_uniq<CAPIResult>();
result->QueryPrepared(prepared);
return result;
}
duckdb_database database = nullptr;
duckdb_connection connection = nullptr;
};
struct CAPIPrepared {
CAPIPrepared() {
}
~CAPIPrepared() {
if (!prepared) {
return;
}
duckdb_destroy_prepare(&prepared);
}
bool Prepare(CAPITester &tester, const string &query) {
auto state = duckdb_prepare(tester.connection, query.c_str(), &prepared);
return state == DuckDBSuccess;
}
duckdb_prepared_statement prepared = nullptr;
};
struct CAPIPending {
CAPIPending() {
}
~CAPIPending() {
if (!pending) {
return;
}
duckdb_destroy_pending(&pending);
}
bool Pending(CAPIPrepared &prepared) {
auto state = duckdb_pending_prepared(prepared.prepared, &pending);
return state == DuckDBSuccess;
}
bool PendingStreaming(CAPIPrepared &prepared) {
auto state = duckdb_pending_prepared_streaming(prepared.prepared, &pending);
return state == DuckDBSuccess;
}
duckdb_pending_state ExecuteTask() {
REQUIRE(pending);
return duckdb_pending_execute_task(pending);
}
unique_ptr<CAPIResult> Execute() {
duckdb_result result;
auto success = duckdb_execute_pending(pending, &result) == DuckDBSuccess;
return make_uniq<CAPIResult>(result, success);
}
duckdb_pending_result pending = nullptr;
};
} // namespace duckdb
bool NO_FAIL(duckdb::CAPIResult &result);
bool NO_FAIL(duckdb::unique_ptr<duckdb::CAPIResult> result);

View File

@@ -0,0 +1,32 @@
//===----------------------------------------------------------------------===//
//
// DuckDB
//
// compare_result.hpp
//
//
//===----------------------------------------------------------------------===//
#pragma once
#include "duckdb/common/string_util.hpp"
#include "duckdb.hpp"
namespace duckdb {
bool CHECK_COLUMN(QueryResult &result, size_t column_number, vector<duckdb::Value> values);
bool CHECK_COLUMN(duckdb::unique_ptr<duckdb::QueryResult> &result, size_t column_number, vector<duckdb::Value> values);
bool CHECK_COLUMN(duckdb::unique_ptr<duckdb::MaterializedQueryResult> &result, size_t column_number,
vector<duckdb::Value> values);
string compare_csv(duckdb::QueryResult &result, string csv, bool header = false);
string compare_csv_collection(duckdb::ColumnDataCollection &collection, string csv, bool header = false);
bool parse_datachunk(string csv, DataChunk &result, vector<LogicalType> sql_types, bool has_header);
//! Compares the result of a pipe-delimited CSV with the given DataChunk
//! Returns true if they are equal, and stores an error_message otherwise
bool compare_result(string csv, ColumnDataCollection &collection, vector<LogicalType> sql_types, bool has_header,
string &error_message);
} // namespace duckdb

16
external/duckdb/test/include/pid.hpp vendored Normal file
View File

@@ -0,0 +1,16 @@
//===----------------------------------------------------------------------===//
//
// DuckDB
//
// pid.hpp
//
//
//===----------------------------------------------------------------------===//
#pragma once
namespace duckdb {
int getpid();
} // namespace duckdb

View File

@@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// DuckDB
//
// sqlite_helpers.hpp
//
//
//===----------------------------------------------------------------------===//
#include "duckdb.hpp"
#include "sqlite3.h"
namespace sqlite {
//! Transfer all data inside the DuckDB connection to the given sqlite database
bool TransferDatabase(duckdb::Connection &con, sqlite3 *sqlite);
//! Fires a query to a SQLite database, returning a QueryResult object. Interrupt should be initially set to 0. If
//! interrupt becomes 1 at any point query execution is cancelled.
duckdb::unique_ptr<duckdb::QueryResult> QueryDatabase(sqlite3 *sqlite, std::string query, volatile int &interrupt);
}; // namespace sqlite

View File

@@ -0,0 +1,129 @@
//===----------------------------------------------------------------------===//
//
// DuckDB
//
// test_config.hpp
//
//
//===----------------------------------------------------------------------===//
#pragma once
#include "duckdb/common/common.hpp"
#include "duckdb/common/optional_idx.hpp"
#include "duckdb/common/enums/debug_vector_verification.hpp"
#include "duckdb/common/types/value.hpp"
#include "duckdb/common/atomic.hpp"
#include "duckdb/common/mutex.hpp"
#include "duckdb/common/enums/debug_initialize.hpp"
#include <sys/types.h>
#include <unordered_map>
namespace duckdb {
enum class SortStyle : uint8_t { NO_SORT, ROW_SORT, VALUE_SORT };
struct ConfigSetting {
string name;
Value value;
};
class TestConfiguration {
public:
enum class ExtensionAutoLoadingMode { NONE = 0, AVAILABLE = 1, ALL = 2 };
enum class SelectPolicy : uint8_t {
NONE, // does not match any explicit policy (default: policy=SELECT)
SELECT, // matches explicit select
SKIP // matches explicit skip
};
static TestConfiguration &Get();
void Initialize();
bool ParseArgument(const string &arg, idx_t argc, char **argv, idx_t &i);
bool TryParseOption(const string &name, const Value &value);
void ParseOption(const string &name, const Value &value);
void LoadConfig(const string &config_path);
void ProcessPath(string &path, const string &test_name);
string GetDescription();
string GetInitialDBPath();
optional_idx GetMaxThreads();
optional_idx GetBlockAllocSize();
idx_t GetCheckpointWALSize();
bool GetForceRestart();
bool GetCheckpointOnShutdown();
bool GetTestMemoryLeaks();
bool RunStorageFuzzer();
bool GetSummarizeFailures();
bool GetSkipCompiledTests();
DebugVectorVerification GetVectorVerification();
DebugInitialize GetDebugInitialize();
ExtensionAutoLoadingMode GetExtensionAutoLoadingMode();
bool ShouldSkipTest(const string &test_name);
string DataLocation();
string OnInitCommand();
string OnLoadCommand();
string OnConnectionCommand();
string OnCleanupCommand();
SortStyle GetDefaultSortStyle();
vector<string> ExtensionToBeLoadedOnLoad();
vector<string> ErrorMessagesToBeSkipped();
string GetStorageVersion();
string GetTestEnv(const string &key, const string &default_value);
const unordered_map<string, string> &GetTestEnvMap();
vector<unordered_set<string>> GetSelectTagSets();
vector<unordered_set<string>> GetSkipTagSets();
SelectPolicy GetPolicyForTagSet(const vector<string> &tag_set);
vector<ConfigSetting> GetConfigSettings();
static bool TestForceStorage();
static bool TestForceReload();
static bool TestMemoryLeaks();
static bool TestRunStorageFuzzer();
static void LoadBaseConfig(const Value &input);
static void ParseConnectScript(const Value &input);
static void CheckSortStyle(const Value &input);
static bool TryParseSortStyle(const string &sort_style, SortStyle &result);
static void AppendSelectTagSet(const Value &tag_set);
static void AppendSkipTagSet(const Value &tag_set);
private:
case_insensitive_map_t<Value> options;
unordered_set<string> tests_to_be_skipped;
unordered_map<string, string> test_env;
vector<unordered_set<string>> select_tag_sets;
vector<unordered_set<string>> skip_tag_sets;
private:
template <class T, class VAL_T = T>
T GetOptionOrDefault(const string &name, T default_val);
static string ReadFileToString(const string &path);
};
class FailureSummary {
public:
FailureSummary();
static void Log(string message);
static string GetFailureSummary();
static idx_t GetSummaryCounter();
static bool SkipLoggingSameError(const string &file_name);
private:
static FailureSummary &Instance();
bool SkipLoggingSameErrorInternal(const string &file_name);
private:
mutex failures_lock;
atomic<idx_t> failures_summary_counter;
vector<string> failures_summary;
set<string> reported_files;
};
} // namespace duckdb

View File

@@ -0,0 +1,77 @@
//===----------------------------------------------------------------------===//
//
// DuckDB
//
// test_helpers.hpp
//
//
//===----------------------------------------------------------------------===//
#pragma once
#ifdef _MSC_VER
// these break enum.hpp otherwise
#undef DELETE
#undef DEFAULT
#undef EXISTS
#undef IN
// this breaks file_system.cpp otherwise
#undef CreateDirectory
#undef RemoveDirectory
#endif
#include "compare_result.hpp"
#include "duckdb.hpp"
#include "duckdb/common/string_util.hpp"
#include "duckdb/common/enum_util.hpp"
#include "duckdb/common/types.hpp"
#include "test_config.hpp"
#include <sstream>
#include <iostream>
namespace duckdb {
void RegisterSqllogictests();
bool SummarizeFailures();
void DeleteDatabase(string path);
void TestDeleteDirectory(string path);
void TestCreateDirectory(string path);
string TestJoinPath(string path1, string path2);
void TestDeleteFile(string path);
void TestChangeDirectory(string path);
void SetDeleteTestPath(bool delete_path);
bool DeleteTestPath();
void ClearTestDirectory();
string TestGetCurrentDirectory();
string TestDirectoryPath();
string TestCreatePath(string suffix);
unique_ptr<DBConfig> GetTestConfig();
bool TestIsInternalError(unordered_set<string> &internal_error_messages, const string &error);
void SetTestDirectory(string path);
void SetDebugInitialize(int value);
void AddRequire(string require);
bool IsRequired(string require);
bool NO_FAIL(QueryResult &result);
bool NO_FAIL(duckdb::unique_ptr<QueryResult> result);
#define REQUIRE_NO_FAIL(result) REQUIRE(NO_FAIL((result)))
#define REQUIRE_FAIL(result) REQUIRE((result)->HasError())
#define COMPARE_CSV(result, csv, header) \
{ \
auto res = compare_csv(*result, csv, header); \
if (!res.empty()) \
FAIL(res); \
}
#define COMPARE_CSV_COLLECTION(collection, csv, header) \
{ \
auto res = compare_csv_collection(collection, csv, header); \
if (!res.empty()) \
FAIL(res); \
}
} // namespace duckdb