#pragma once
#define DUCKDB_AMALGAMATION 1
#define DUCKDB_SOURCE_ID "b00b93f0b1"
#define DUCKDB_VERSION "v0.7.1"
#include <memory>
#include <cstdint>
#include <string>
#include <sstream>
namespace duckdb {
using std::string;
}
#ifndef DUCKDB_API
#ifdef _WIN32
#if defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION)
#define DUCKDB_API __declspec(dllexport)
#else
#define DUCKDB_API __declspec(dllimport)
#endif
#else
#define DUCKDB_API
#endif
#endif
#ifndef DUCKDB_EXTENSION_API
#ifdef _WIN32
#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION
#define DUCKDB_EXTENSION_API __declspec(dllexport)
#else
#define DUCKDB_EXTENSION_API
#endif
#else
#define DUCKDB_EXTENSION_API __attribute__((visibility("default")))
#endif
#endif
namespace duckdb {
#ifndef DUCKDB_API_0_3_1
#define DUCKDB_API_0_3_1 1
#endif
#ifndef DUCKDB_API_0_3_2
#define DUCKDB_API_0_3_2 2
#endif
#ifndef DUCKDB_API_LATEST
#define DUCKDB_API_LATEST DUCKDB_API_0_3_2
#endif
#ifndef DUCKDB_API_VERSION
#define DUCKDB_API_VERSION DUCKDB_API_LATEST
#endif
#ifndef DUCKDB_DEBUG_MOVE
using std::move;
#endif
using std::shared_ptr;
using std::unique_ptr;
using std::weak_ptr;
using data_ptr = unique_ptr<char[]>;
using std::make_shared;
#define DEFAULT_SCHEMA "main"
#define INVALID_SCHEMA ""
#define INVALID_CATALOG ""
#define SYSTEM_CATALOG "system"
#define TEMP_CATALOG "temp"
DUCKDB_API bool IsInvalidSchema(const string &str);
DUCKDB_API bool IsInvalidCatalog(const string &str);
typedef uint64_t idx_t;
typedef int64_t row_t;
typedef uint64_t hash_t;
typedef uint8_t data_t;
typedef data_t *data_ptr_t;
typedef const data_t *const_data_ptr_t;
typedef uint32_t sel_t;
typedef idx_t transaction_t;
typedef idx_t column_t;
typedef idx_t storage_t;
DUCKDB_API extern const column_t COLUMN_IDENTIFIER_ROW_ID;
DUCKDB_API bool IsRowIdColumnId(column_t column_id);
extern const row_t MAX_ROW_ID;
extern const transaction_t TRANSACTION_ID_START;
extern const transaction_t MAX_TRANSACTION_ID;
extern const transaction_t MAXIMUM_QUERY_ID;
extern const transaction_t NOT_DELETED_ID;
extern const double PI;
struct DConstants {
static constexpr const idx_t INVALID_INDEX = idx_t(-1);
};
struct Storage {
constexpr static int SECTOR_SIZE = 4096;
constexpr static int BLOCK_HEADER_SIZE = sizeof(uint64_t);
constexpr static int BLOCK_ALLOC_SIZE = 262144;
constexpr static int BLOCK_SIZE = BLOCK_ALLOC_SIZE - BLOCK_HEADER_SIZE;
constexpr static int FILE_HEADER_SIZE = 4096;
};
struct LogicalIndex {
explicit LogicalIndex(idx_t index) : index(index) {
}
idx_t index;
inline bool operator==(const LogicalIndex &rhs) const {
return index == rhs.index;
};
inline bool operator!=(const LogicalIndex &rhs) const {
return index != rhs.index;
};
inline bool operator<(const LogicalIndex &rhs) const {
return index < rhs.index;
};
bool IsValid() {
return index != DConstants::INVALID_INDEX;
}
};
struct PhysicalIndex {
explicit PhysicalIndex(idx_t index) : index(index) {
}
idx_t index;
inline bool operator==(const PhysicalIndex &rhs) const {
return index == rhs.index;
};
inline bool operator!=(const PhysicalIndex &rhs) const {
return index != rhs.index;
};
inline bool operator<(const PhysicalIndex &rhs) const {
return index < rhs.index;
};
bool IsValid() {
return index != DConstants::INVALID_INDEX;
}
};
DUCKDB_API uint64_t NextPowerOfTwo(uint64_t v);
}
namespace duckdb {
enum class ProfilerPrintFormat : uint8_t { QUERY_TREE, JSON, QUERY_TREE_OPTIMIZER };
}
#include <string.h>
#ifdef _MSC_VER
#define suint64_t int64_t
#endif
#if defined(_WIN32) || defined(_WIN64)
#define DUCKDB_WINDOWS
#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
#define DUCKDB_POSIX
#endif
namespace duckdb {
#ifndef __has_cpp_attribute
#define __has_cpp_attribute(x) 0
#endif
#if __has_cpp_attribute(clang::fallthrough)
#define DUCKDB_EXPLICIT_FALLTHROUGH [[clang::fallthrough]]
#elif __has_cpp_attribute(gnu::fallthrough)
#define DUCKDB_EXPLICIT_FALLTHROUGH [[gnu::fallthrough]]
#else
#define DUCKDB_EXPLICIT_FALLTHROUGH
#endif
#if !defined(_MSC_VER) && (__cplusplus < 201402L)
template <typename T, typename... Args>
unique_ptr<T> make_unique(Args &&... args) {
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#else
using std::make_unique;
#endif
template <typename S, typename T, typename... Args>
unique_ptr<S> make_unique_base(Args &&... args) {
return unique_ptr<S>(new T(std::forward<Args>(args)...));
}
template <typename T, typename S>
unique_ptr<S> unique_ptr_cast(unique_ptr<T> src) {
return unique_ptr<S>(static_cast<S *>(src.release()));
}
struct SharedConstructor {
template <class T, typename... ARGS>
static shared_ptr<T> Create(ARGS &&...args) {
return make_shared<T>(std::forward<ARGS>(args)...);
}
};
struct UniqueConstructor {
template <class T, typename... ARGS>
static unique_ptr<T> Create(ARGS &&...args) {
return make_unique<T>(std::forward<ARGS>(args)...);
}
};
#ifdef DUCKDB_DEBUG_MOVE
template<class T>
typename std::remove_reference<T>::type&& move(T&& t) noexcept {
static_assert(sizeof(T) == 0, "Use std::move instead of unqualified move or duckdb::move");
}
#endif
template <typename T>
T MaxValue(T a, T b) {
return a > b ? a : b;
}
template <typename T>
T MinValue(T a, T b) {
return a < b ? a : b;
}
template <typename T>
T AbsValue(T a) {
return a < 0 ? -a : a;
}
template<class T, T val=8>
static inline T AlignValue(T n) {
return ((n + (val - 1)) / val) * val;
}
template<class T, T val=8>
static inline bool ValueIsAligned(T n) {
return (n % val) == 0;
}
template <typename T>
T SignValue(T a) {
return a < 0 ? -1 : 1;
}
template <typename T>
const T Load(const_data_ptr_t ptr) {
T ret;
memcpy(&ret, ptr, sizeof(ret));
return ret;
}
template <typename T>
void Store(const T val, data_ptr_t ptr) {
memcpy(ptr, (void *)&val, sizeof(val));
}
template<class T>
void AssignSharedPointer(shared_ptr<T> &target, const shared_ptr<T> &source) {
if (target.get() != source.get()) {
target = source;
}
}
}
#if (defined(DUCKDB_USE_STANDARD_ASSERT) || !defined(DEBUG)) && !defined(DUCKDB_FORCE_ASSERT)
#include <assert.h>
#define D_ASSERT assert
namespace duckdb {
DUCKDB_API void DuckDBAssertInternal(bool condition, const char *condition_name, const char *file, int linenr);
}
#else
namespace duckdb {
DUCKDB_API void DuckDBAssertInternal(bool condition, const char *condition_name, const char *file, int linenr);
}
#define D_ASSERT(condition) duckdb::DuckDBAssertInternal(bool(condition), #condition, __FILE__, __LINE__)
#endif
class RefCounter {
public:
uint32_t pn;
RefCounter() : pn(1) {
}
void inc() {
++pn;
}
void dec() {
--pn;
}
uint32_t getPn() const {
return pn;
}
virtual ~RefCounter() {
}
};
namespace duckdb {
template <typename T>
class single_thread_ptr {
public:
T *ptr; RefCounter *ref_count;
public:
constexpr single_thread_ptr() : ptr(nullptr), ref_count(nullptr) {
}
constexpr single_thread_ptr(std::nullptr_t) : ptr(nullptr), ref_count(nullptr) {
}
single_thread_ptr(RefCounter *r, T *p) {
ptr = p;
ref_count = r;
}
template <class U>
single_thread_ptr(RefCounter *r, U *p) {
ptr = p;
ref_count = r;
}
single_thread_ptr(const single_thread_ptr &sp) : ptr(nullptr), ref_count(nullptr) {
if (sp.ptr) {
ptr = sp.ptr;
ref_count = sp.ref_count;
ref_count->inc();
}
}
template <typename U>
single_thread_ptr(const single_thread_ptr<U> &sp) : ptr(nullptr), ref_count(nullptr) {
if (sp.ptr) {
ptr = sp.ptr;
ref_count = sp.ref_count;
ref_count->inc();
}
}
single_thread_ptr(single_thread_ptr &&sp) noexcept : ptr {sp.ptr}, ref_count {sp.ref_count} {
sp.ptr = nullptr;
sp.ref_count = nullptr;
}
template <class U>
single_thread_ptr(single_thread_ptr<U> &&sp) noexcept : ptr {sp.ptr}, ref_count {sp.ref_count} {
sp.ptr = nullptr;
sp.ref_count = nullptr;
}
~single_thread_ptr() {
release();
}
void release() {
if (ptr && ref_count) {
ref_count->dec();
if ((ref_count->getPn()) == 0) {
delete ref_count;
}
}
ref_count = nullptr;
ptr = nullptr;
}
single_thread_ptr &operator=(single_thread_ptr sp) noexcept {
std::swap(this->ptr, sp.ptr);
std::swap(this->ref_count, sp.ref_count);
return *this;
}
T &operator*() const noexcept {
return *ptr;
}
T *operator->() const noexcept {
return ptr;
}
T *get() const noexcept {
return ptr;
}
long use_count() const noexcept {
if (ptr)
return ref_count->getPn();
else
return 0;
}
explicit operator bool() const noexcept {
return (ptr);
}
void reset() noexcept {
release();
}
};
template <class T>
struct _object_and_block : public RefCounter {
T object;
template <class... Args>
explicit _object_and_block(Args &&... args) : object(std::forward<Args>(args)...) {
}
};
template <typename T, typename U>
inline bool operator==(const single_thread_ptr<T> &sp1, const single_thread_ptr<U> &sp2) {
return sp1.get() == sp2.get();
}
template <typename T>
inline bool operator==(const single_thread_ptr<T> &sp, std::nullptr_t) noexcept {
return !sp;
}
template <typename T, typename U>
inline bool operator!=(const single_thread_ptr<T> &sp1, const single_thread_ptr<U> &sp2) {
return sp1.get() != sp2.get();
}
template <typename T>
inline bool operator!=(const single_thread_ptr<T> &sp, std::nullptr_t) noexcept {
return sp.get();
}
template <typename T>
inline bool operator!=(std::nullptr_t, const single_thread_ptr<T> &sp) noexcept {
return sp.get();
}
template <class T, class... Args>
single_thread_ptr<T> single_thread_make_shared(Args &&... args) {
auto tmp_object = new _object_and_block<T>(std::forward<Args>(args)...);
return single_thread_ptr<T>(tmp_object, &(tmp_object->object));
}
}
#include <vector>
namespace duckdb {
using std::vector;
}
#include <limits>
namespace duckdb {
class Serializer;
class Deserializer;
class Value;
class TypeCatalogEntry;
class Vector;
class ClientContext;
struct hugeint_t {
public:
uint64_t lower;
int64_t upper;
public:
DUCKDB_API hugeint_t() = default;
DUCKDB_API hugeint_t(int64_t value); DUCKDB_API constexpr hugeint_t(int64_t upper, uint64_t lower): lower(lower), upper(upper) {};
DUCKDB_API constexpr hugeint_t(const hugeint_t &rhs) = default;
DUCKDB_API constexpr hugeint_t(hugeint_t &&rhs) = default;
DUCKDB_API hugeint_t &operator=(const hugeint_t &rhs) = default;
DUCKDB_API hugeint_t &operator=(hugeint_t &&rhs) = default;
DUCKDB_API string ToString() const;
DUCKDB_API bool operator==(const hugeint_t &rhs) const;
DUCKDB_API bool operator!=(const hugeint_t &rhs) const;
DUCKDB_API bool operator<=(const hugeint_t &rhs) const;
DUCKDB_API bool operator<(const hugeint_t &rhs) const;
DUCKDB_API bool operator>(const hugeint_t &rhs) const;
DUCKDB_API bool operator>=(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator+(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator-(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator*(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator/(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator%(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator-() const;
DUCKDB_API hugeint_t operator>>(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator<<(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator&(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator|(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator^(const hugeint_t &rhs) const;
DUCKDB_API hugeint_t operator~() const;
DUCKDB_API hugeint_t &operator+=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator-=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator*=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator/=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator%=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator>>=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator<<=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator&=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator|=(const hugeint_t &rhs);
DUCKDB_API hugeint_t &operator^=(const hugeint_t &rhs);
};
struct string_t;
template <class T>
using child_list_t = std::vector<std::pair<std::string, T>>;
template <class T>
using buffer_ptr = shared_ptr<T>;
template <class T, typename... Args>
buffer_ptr<T> make_buffer(Args &&...args) {
return make_shared<T>(std::forward<Args>(args)...);
}
struct list_entry_t {
list_entry_t() = default;
list_entry_t(uint64_t offset, uint64_t length) : offset(offset), length(length) {
}
uint64_t offset;
uint64_t length;
};
using union_tag_t = uint8_t;
enum class PhysicalType : uint8_t {
BOOL = 1,
UINT8 = 2,
INT8 = 3,
UINT16 = 4,
INT16 = 5,
UINT32 = 6,
INT32 = 7,
UINT64 = 8,
INT64 = 9,
FLOAT = 11,
DOUBLE = 12,
INTERVAL = 21,
LIST = 23,
STRUCT = 24,
VARCHAR = 200, INT128 = 204, UNKNOWN = 205, BIT = 206,
INVALID = 255
};
enum class LogicalTypeId : uint8_t {
INVALID = 0,
SQLNULL = 1,
UNKNOWN = 2,
ANY = 3,
USER = 4,
BOOLEAN = 10,
TINYINT = 11,
SMALLINT = 12,
INTEGER = 13,
BIGINT = 14,
DATE = 15,
TIME = 16,
TIMESTAMP_SEC = 17,
TIMESTAMP_MS = 18,
TIMESTAMP = 19, TIMESTAMP_NS = 20,
DECIMAL = 21,
FLOAT = 22,
DOUBLE = 23,
CHAR = 24,
VARCHAR = 25,
BLOB = 26,
INTERVAL = 27,
UTINYINT = 28,
USMALLINT = 29,
UINTEGER = 30,
UBIGINT = 31,
TIMESTAMP_TZ = 32,
TIME_TZ = 34,
BIT = 36,
HUGEINT = 50,
POINTER = 51,
VALIDITY = 53,
UUID = 54,
STRUCT = 100,
LIST = 101,
MAP = 102,
TABLE = 103,
ENUM = 104,
AGGREGATE_STATE = 105,
LAMBDA = 106,
UNION = 107
};
struct ExtraTypeInfo;
struct aggregate_state_t;
struct LogicalType {
DUCKDB_API LogicalType();
DUCKDB_API LogicalType(LogicalTypeId id); DUCKDB_API LogicalType(LogicalTypeId id, shared_ptr<ExtraTypeInfo> type_info);
DUCKDB_API LogicalType(const LogicalType &other);
DUCKDB_API LogicalType(LogicalType &&other) noexcept;
DUCKDB_API ~LogicalType();
inline LogicalTypeId id() const {
return id_;
}
inline PhysicalType InternalType() const {
return physical_type_;
}
inline const ExtraTypeInfo *AuxInfo() const {
return type_info_.get();
}
inline void CopyAuxInfo(const LogicalType& other) {
type_info_ = other.type_info_;
}
bool EqualTypeInfo(const LogicalType& rhs) const;
inline LogicalType& operator=(const LogicalType &other) {
id_ = other.id_;
physical_type_ = other.physical_type_;
type_info_ = other.type_info_;
return *this;
}
inline LogicalType& operator=(LogicalType&& other) noexcept {
id_ = other.id_;
physical_type_ = other.physical_type_;
type_info_ = std::move(other.type_info_);
return *this;
}
DUCKDB_API bool operator==(const LogicalType &rhs) const;
inline bool operator!=(const LogicalType &rhs) const {
return !(*this == rhs);
}
DUCKDB_API void Serialize(Serializer &serializer) const;
DUCKDB_API static LogicalType Deserialize(Deserializer &source);
DUCKDB_API static bool TypeIsTimestamp(LogicalTypeId id) {
return (id == LogicalTypeId::TIMESTAMP ||
id == LogicalTypeId::TIMESTAMP_MS ||
id == LogicalTypeId::TIMESTAMP_NS ||
id == LogicalTypeId::TIMESTAMP_SEC ||
id == LogicalTypeId::TIMESTAMP_TZ);
}
DUCKDB_API static bool TypeIsTimestamp(const LogicalType& type) {
return TypeIsTimestamp(type.id());
}
DUCKDB_API string ToString() const;
DUCKDB_API bool IsIntegral() const;
DUCKDB_API bool IsNumeric() const;
DUCKDB_API hash_t Hash() const;
DUCKDB_API void SetAlias(string alias);
DUCKDB_API bool HasAlias() const;
DUCKDB_API string GetAlias() const;
DUCKDB_API static LogicalType MaxLogicalType(const LogicalType &left, const LogicalType &right);
DUCKDB_API static void SetCatalog(LogicalType &type, TypeCatalogEntry* catalog_entry);
DUCKDB_API static TypeCatalogEntry* GetCatalog(const LogicalType &type);
DUCKDB_API bool GetDecimalProperties(uint8_t &width, uint8_t &scale) const;
DUCKDB_API void Verify() const;
DUCKDB_API bool IsValid() const;
private:
LogicalTypeId id_;
PhysicalType physical_type_;
shared_ptr<ExtraTypeInfo> type_info_;
private:
PhysicalType GetInternalType();
public:
static constexpr const LogicalTypeId SQLNULL = LogicalTypeId::SQLNULL;
static constexpr const LogicalTypeId UNKNOWN = LogicalTypeId::UNKNOWN;
static constexpr const LogicalTypeId BOOLEAN = LogicalTypeId::BOOLEAN;
static constexpr const LogicalTypeId TINYINT = LogicalTypeId::TINYINT;
static constexpr const LogicalTypeId UTINYINT = LogicalTypeId::UTINYINT;
static constexpr const LogicalTypeId SMALLINT = LogicalTypeId::SMALLINT;
static constexpr const LogicalTypeId USMALLINT = LogicalTypeId::USMALLINT;
static constexpr const LogicalTypeId INTEGER = LogicalTypeId::INTEGER;
static constexpr const LogicalTypeId UINTEGER = LogicalTypeId::UINTEGER;
static constexpr const LogicalTypeId BIGINT = LogicalTypeId::BIGINT;
static constexpr const LogicalTypeId UBIGINT = LogicalTypeId::UBIGINT;
static constexpr const LogicalTypeId FLOAT = LogicalTypeId::FLOAT;
static constexpr const LogicalTypeId DOUBLE = LogicalTypeId::DOUBLE;
static constexpr const LogicalTypeId DATE = LogicalTypeId::DATE;
static constexpr const LogicalTypeId TIMESTAMP = LogicalTypeId::TIMESTAMP;
static constexpr const LogicalTypeId TIMESTAMP_S = LogicalTypeId::TIMESTAMP_SEC;
static constexpr const LogicalTypeId TIMESTAMP_MS = LogicalTypeId::TIMESTAMP_MS;
static constexpr const LogicalTypeId TIMESTAMP_NS = LogicalTypeId::TIMESTAMP_NS;
static constexpr const LogicalTypeId TIME = LogicalTypeId::TIME;
static constexpr const LogicalTypeId TIMESTAMP_TZ = LogicalTypeId::TIMESTAMP_TZ;
static constexpr const LogicalTypeId TIME_TZ = LogicalTypeId::TIME_TZ;
static constexpr const LogicalTypeId VARCHAR = LogicalTypeId::VARCHAR;
static constexpr const LogicalTypeId ANY = LogicalTypeId::ANY;
static constexpr const LogicalTypeId BLOB = LogicalTypeId::BLOB;
static constexpr const LogicalTypeId BIT = LogicalTypeId::BIT;
static constexpr const LogicalTypeId INTERVAL = LogicalTypeId::INTERVAL;
static constexpr const LogicalTypeId HUGEINT = LogicalTypeId::HUGEINT;
static constexpr const LogicalTypeId UUID = LogicalTypeId::UUID;
static constexpr const LogicalTypeId HASH = LogicalTypeId::UBIGINT;
static constexpr const LogicalTypeId POINTER = LogicalTypeId::POINTER;
static constexpr const LogicalTypeId TABLE = LogicalTypeId::TABLE;
static constexpr const LogicalTypeId LAMBDA = LogicalTypeId::LAMBDA;
static constexpr const LogicalTypeId INVALID = LogicalTypeId::INVALID;
static constexpr const LogicalTypeId ROW_TYPE = LogicalTypeId::BIGINT;
DUCKDB_API static LogicalType DECIMAL(int width, int scale); DUCKDB_API static LogicalType VARCHAR_COLLATION(string collation); DUCKDB_API static LogicalType LIST( LogicalType child); DUCKDB_API static LogicalType STRUCT( child_list_t<LogicalType> children); DUCKDB_API static LogicalType AGGREGATE_STATE(aggregate_state_t state_type); DUCKDB_API static LogicalType MAP(LogicalType child); DUCKDB_API static LogicalType MAP( child_list_t<LogicalType> children); DUCKDB_API static LogicalType MAP(LogicalType key, LogicalType value); DUCKDB_API static LogicalType UNION( child_list_t<LogicalType> members); DUCKDB_API static LogicalType ENUM(const string &enum_name, Vector &ordered_data, idx_t size); DUCKDB_API static LogicalType USER(const string &user_type_name); DUCKDB_API static const vector<LogicalType> Numeric();
DUCKDB_API static const vector<LogicalType> Integral();
DUCKDB_API static const vector<LogicalType> AllTypes();
};
struct DecimalType {
DUCKDB_API static uint8_t GetWidth(const LogicalType &type);
DUCKDB_API static uint8_t GetScale(const LogicalType &type);
DUCKDB_API static uint8_t MaxWidth();
};
struct StringType {
DUCKDB_API static string GetCollation(const LogicalType &type);
};
struct ListType {
DUCKDB_API static const LogicalType &GetChildType(const LogicalType &type);
};
struct UserType{
DUCKDB_API static const string &GetTypeName(const LogicalType &type);
};
struct EnumType{
DUCKDB_API static const string &GetTypeName(const LogicalType &type);
DUCKDB_API static int64_t GetPos(const LogicalType &type, const string_t& key);
DUCKDB_API static Vector &GetValuesInsertOrder(const LogicalType &type);
DUCKDB_API static idx_t GetSize(const LogicalType &type);
DUCKDB_API static const string GetValue(const Value &val);
DUCKDB_API static void SetCatalog(LogicalType &type, TypeCatalogEntry* catalog_entry);
DUCKDB_API static TypeCatalogEntry* GetCatalog(const LogicalType &type);
DUCKDB_API static PhysicalType GetPhysicalType(const LogicalType &type);
};
struct StructType {
DUCKDB_API static const child_list_t<LogicalType> &GetChildTypes(const LogicalType &type);
DUCKDB_API static const LogicalType &GetChildType(const LogicalType &type, idx_t index);
DUCKDB_API static const string &GetChildName(const LogicalType &type, idx_t index);
DUCKDB_API static idx_t GetChildCount(const LogicalType &type);
};
struct MapType {
DUCKDB_API static const LogicalType &KeyType(const LogicalType &type);
DUCKDB_API static const LogicalType &ValueType(const LogicalType &type);
};
struct UnionType {
DUCKDB_API static const idx_t MAX_UNION_MEMBERS = 256;
DUCKDB_API static idx_t GetMemberCount(const LogicalType &type);
DUCKDB_API static const LogicalType &GetMemberType(const LogicalType &type, idx_t index);
DUCKDB_API static const string &GetMemberName(const LogicalType &type, idx_t index);
DUCKDB_API static const child_list_t<LogicalType> CopyMemberTypes(const LogicalType &type);
};
struct AggregateStateType {
DUCKDB_API static const string GetTypeName(const LogicalType &type);
DUCKDB_API static const aggregate_state_t &GetStateType(const LogicalType &type);
};
DUCKDB_API string LogicalTypeIdToString(LogicalTypeId type);
DUCKDB_API LogicalTypeId TransformStringToLogicalTypeId(const string &str);
DUCKDB_API LogicalType TransformStringToLogicalType(const string &str);
DUCKDB_API LogicalType TransformStringToLogicalType(const string &str, ClientContext &context);
extern const PhysicalType ROW_TYPE;
DUCKDB_API string TypeIdToString(PhysicalType type);
DUCKDB_API idx_t GetTypeIdSize(PhysicalType type);
DUCKDB_API bool TypeIsConstantSize(PhysicalType type);
DUCKDB_API bool TypeIsIntegral(PhysicalType type);
DUCKDB_API bool TypeIsNumeric(PhysicalType type);
DUCKDB_API bool TypeIsInteger(PhysicalType type);
bool ApproxEqual(float l, float r);
bool ApproxEqual(double l, double r);
struct aggregate_state_t {
aggregate_state_t(string function_name_p, LogicalType return_type_p, vector<LogicalType> bound_argument_types_p) : function_name(std::move(function_name_p)), return_type(std::move(return_type_p)), bound_argument_types(std::move(bound_argument_types_p)) {
}
string function_name;
LogicalType return_type;
vector<LogicalType> bound_argument_types;
};
}
namespace duckdb {
enum class ExceptionFormatValueType : uint8_t {
FORMAT_VALUE_TYPE_DOUBLE,
FORMAT_VALUE_TYPE_INTEGER,
FORMAT_VALUE_TYPE_STRING
};
struct ExceptionFormatValue {
DUCKDB_API ExceptionFormatValue(double dbl_val); DUCKDB_API ExceptionFormatValue(int64_t int_val); DUCKDB_API ExceptionFormatValue(string str_val); DUCKDB_API ExceptionFormatValue(hugeint_t hg_val);
ExceptionFormatValueType type;
double dbl_val = 0;
int64_t int_val = 0;
string str_val;
public:
template <class T>
static ExceptionFormatValue CreateFormatValue(T value) {
return int64_t(value);
}
static string Format(const string &msg, vector<ExceptionFormatValue> &values);
};
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(PhysicalType value);
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(LogicalType value);
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(float value);
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(double value);
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(string value);
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(const char *value);
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(char *value);
template <>
DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(hugeint_t value);
}
#include <stdexcept>
namespace duckdb {
enum class PhysicalType : uint8_t;
struct LogicalType;
struct hugeint_t;
inline void assert_restrict_function(void *left_start, void *left_end, void *right_start, void *right_end,
const char *fname, int linenr) {
#ifdef DEBUG
if (!(left_end <= right_start || right_end <= left_start)) {
printf("ASSERT RESTRICT FAILED: %s:%d\n", fname, linenr);
D_ASSERT(0);
}
#endif
}
#define ASSERT_RESTRICT(left_start, left_end, right_start, right_end) \
assert_restrict_function(left_start, left_end, right_start, right_end, __FILE__, __LINE__)
enum class ExceptionType {
INVALID = 0, OUT_OF_RANGE = 1, CONVERSION = 2, UNKNOWN_TYPE = 3, DECIMAL = 4, MISMATCH_TYPE = 5, DIVIDE_BY_ZERO = 6, OBJECT_SIZE = 7, INVALID_TYPE = 8, SERIALIZATION = 9, TRANSACTION = 10, NOT_IMPLEMENTED = 11, EXPRESSION = 12, CATALOG = 13, PARSER = 14, PLANNER = 15, SCHEDULER = 16, EXECUTOR = 17, CONSTRAINT = 18, INDEX = 19, STAT = 20, CONNECTION = 21, SYNTAX = 22, SETTINGS = 23, BINDER = 24, NETWORK = 25, OPTIMIZER = 26, NULL_POINTER = 27, IO = 28, INTERRUPT = 29, FATAL = 30, INTERNAL = 31, INVALID_INPUT = 32, OUT_OF_MEMORY = 33, PERMISSION = 34, PARAMETER_NOT_RESOLVED = 35, PARAMETER_NOT_ALLOWED = 36, DEPENDENCY = 37 };
class Exception : public std::exception {
public:
DUCKDB_API explicit Exception(const string &msg);
DUCKDB_API Exception(ExceptionType exception_type, const string &message);
ExceptionType type;
public:
DUCKDB_API const char *what() const noexcept override;
DUCKDB_API const string &RawMessage() const;
DUCKDB_API static string ExceptionTypeToString(ExceptionType type);
[[noreturn]] DUCKDB_API static void ThrowAsTypeWithMessage(ExceptionType type, const string &message);
template <typename... Args>
static string ConstructMessage(const string &msg, Args... params) {
vector<ExceptionFormatValue> values;
return ConstructMessageRecursive(msg, values, params...);
}
DUCKDB_API static string ConstructMessageRecursive(const string &msg, vector<ExceptionFormatValue> &values);
template <class T, typename... Args>
static string ConstructMessageRecursive(const string &msg, vector<ExceptionFormatValue> &values, T param,
Args... params) {
values.push_back(ExceptionFormatValue::CreateFormatValue<T>(param));
return ConstructMessageRecursive(msg, values, params...);
}
DUCKDB_API static bool UncaughtException();
DUCKDB_API static string GetStackTrace(int max_depth = 120);
private:
string exception_message_;
string raw_message_;
};
class StandardException : public Exception {
public:
DUCKDB_API StandardException(ExceptionType exception_type, const string &message);
};
class CatalogException : public StandardException {
public:
DUCKDB_API explicit CatalogException(const string &msg);
template <typename... Args>
explicit CatalogException(const string &msg, Args... params) : CatalogException(ConstructMessage(msg, params...)) {
}
};
class ConnectionException : public StandardException {
public:
DUCKDB_API explicit ConnectionException(const string &msg);
template <typename... Args>
explicit ConnectionException(const string &msg, Args... params)
: ConnectionException(ConstructMessage(msg, params...)) {
}
};
class ParserException : public StandardException {
public:
DUCKDB_API explicit ParserException(const string &msg);
template <typename... Args>
explicit ParserException(const string &msg, Args... params) : ParserException(ConstructMessage(msg, params...)) {
}
};
class PermissionException : public StandardException {
public:
DUCKDB_API explicit PermissionException(const string &msg);
template <typename... Args>
explicit PermissionException(const string &msg, Args... params)
: PermissionException(ConstructMessage(msg, params...)) {
}
};
class BinderException : public StandardException {
public:
DUCKDB_API explicit BinderException(const string &msg);
template <typename... Args>
explicit BinderException(const string &msg, Args... params) : BinderException(ConstructMessage(msg, params...)) {
}
};
class ConversionException : public Exception {
public:
DUCKDB_API explicit ConversionException(const string &msg);
template <typename... Args>
explicit ConversionException(const string &msg, Args... params)
: ConversionException(ConstructMessage(msg, params...)) {
}
};
class TransactionException : public Exception {
public:
DUCKDB_API explicit TransactionException(const string &msg);
template <typename... Args>
explicit TransactionException(const string &msg, Args... params)
: TransactionException(ConstructMessage(msg, params...)) {
}
};
class NotImplementedException : public Exception {
public:
DUCKDB_API explicit NotImplementedException(const string &msg);
template <typename... Args>
explicit NotImplementedException(const string &msg, Args... params)
: NotImplementedException(ConstructMessage(msg, params...)) {
}
};
class OutOfRangeException : public Exception {
public:
DUCKDB_API explicit OutOfRangeException(const string &msg);
template <typename... Args>
explicit OutOfRangeException(const string &msg, Args... params)
: OutOfRangeException(ConstructMessage(msg, params...)) {
}
};
class OutOfMemoryException : public Exception {
public:
DUCKDB_API explicit OutOfMemoryException(const string &msg);
template <typename... Args>
explicit OutOfMemoryException(const string &msg, Args... params)
: OutOfMemoryException(ConstructMessage(msg, params...)) {
}
};
class SyntaxException : public Exception {
public:
DUCKDB_API explicit SyntaxException(const string &msg);
template <typename... Args>
explicit SyntaxException(const string &msg, Args... params) : SyntaxException(ConstructMessage(msg, params...)) {
}
};
class ConstraintException : public Exception {
public:
DUCKDB_API explicit ConstraintException(const string &msg);
template <typename... Args>
explicit ConstraintException(const string &msg, Args... params)
: ConstraintException(ConstructMessage(msg, params...)) {
}
};
class DependencyException : public Exception {
public:
DUCKDB_API explicit DependencyException(const string &msg);
template <typename... Args>
explicit DependencyException(const string &msg, Args... params)
: DependencyException(ConstructMessage(msg, params...)) {
}
};
class IOException : public Exception {
public:
DUCKDB_API explicit IOException(const string &msg);
template <typename... Args>
explicit IOException(const string &msg, Args... params) : IOException(ConstructMessage(msg, params...)) {
}
};
class MissingExtensionException : public IOException {
public:
DUCKDB_API explicit MissingExtensionException(const string &msg);
template <typename... Args>
explicit MissingExtensionException(const string &msg, Args... params)
: IOException(ConstructMessage(msg, params...)) {
}
};
class SerializationException : public Exception {
public:
DUCKDB_API explicit SerializationException(const string &msg);
template <typename... Args>
explicit SerializationException(const string &msg, Args... params)
: SerializationException(ConstructMessage(msg, params...)) {
}
};
class SequenceException : public Exception {
public:
DUCKDB_API explicit SequenceException(const string &msg);
template <typename... Args>
explicit SequenceException(const string &msg, Args... params)
: SequenceException(ConstructMessage(msg, params...)) {
}
};
class InterruptException : public Exception {
public:
DUCKDB_API InterruptException();
};
class FatalException : public Exception {
public:
DUCKDB_API explicit FatalException(const string &msg) : FatalException(ExceptionType::FATAL, msg) {
}
template <typename... Args>
explicit FatalException(const string &msg, Args... params) : FatalException(ConstructMessage(msg, params...)) {
}
protected:
DUCKDB_API explicit FatalException(ExceptionType type, const string &msg);
template <typename... Args>
explicit FatalException(ExceptionType type, const string &msg, Args... params)
: FatalException(type, ConstructMessage(msg, params...)) {
}
};
class InternalException : public FatalException {
public:
DUCKDB_API explicit InternalException(const string &msg);
template <typename... Args>
explicit InternalException(const string &msg, Args... params)
: InternalException(ConstructMessage(msg, params...)) {
}
};
class InvalidInputException : public Exception {
public:
DUCKDB_API explicit InvalidInputException(const string &msg);
template <typename... Args>
explicit InvalidInputException(const string &msg, Args... params)
: InvalidInputException(ConstructMessage(msg, params...)) {
}
};
class CastException : public Exception {
public:
DUCKDB_API CastException(const PhysicalType origType, const PhysicalType newType);
DUCKDB_API CastException(const LogicalType &origType, const LogicalType &newType);
DUCKDB_API
CastException(const string &msg); };
class InvalidTypeException : public Exception {
public:
DUCKDB_API InvalidTypeException(PhysicalType type, const string &msg);
DUCKDB_API InvalidTypeException(const LogicalType &type, const string &msg);
DUCKDB_API
InvalidTypeException(const string &msg); };
class TypeMismatchException : public Exception {
public:
DUCKDB_API TypeMismatchException(const PhysicalType type_1, const PhysicalType type_2, const string &msg);
DUCKDB_API TypeMismatchException(const LogicalType &type_1, const LogicalType &type_2, const string &msg);
DUCKDB_API
TypeMismatchException(const string &msg); };
class ValueOutOfRangeException : public Exception {
public:
DUCKDB_API ValueOutOfRangeException(const int64_t value, const PhysicalType origType, const PhysicalType newType);
DUCKDB_API ValueOutOfRangeException(const hugeint_t value, const PhysicalType origType, const PhysicalType newType);
DUCKDB_API ValueOutOfRangeException(const double value, const PhysicalType origType, const PhysicalType newType);
DUCKDB_API ValueOutOfRangeException(const PhysicalType varType, const idx_t length);
DUCKDB_API ValueOutOfRangeException(
const string &msg); };
class ParameterNotAllowedException : public StandardException {
public:
DUCKDB_API explicit ParameterNotAllowedException(const string &msg);
template <typename... Args>
explicit ParameterNotAllowedException(const string &msg, Args... params)
: ParameterNotAllowedException(ConstructMessage(msg, params...)) {
}
};
class ParameterNotResolvedException : public Exception {
public:
DUCKDB_API explicit ParameterNotResolvedException();
};
}
#include <type_traits>
namespace duckdb {
class Serializer {
private:
uint64_t version = 0L;
public:
virtual ~Serializer() {
}
void SetVersion(uint64_t v) {
D_ASSERT(this->version == 0); this->version = v;
}
uint64_t GetVersion() {
return version;
}
virtual void WriteData(const_data_ptr_t buffer, idx_t write_size) = 0;
template <class T>
void Write(T element) {
static_assert(std::is_trivially_destructible<T>(), "Write element must be trivially destructible");
WriteData((const_data_ptr_t)&element, sizeof(T));
}
void WriteBufferData(const string &str) {
WriteData((const_data_ptr_t)str.c_str(), str.size());
}
void WriteString(const string &val) {
WriteStringLen((const_data_ptr_t)val.c_str(), val.size());
}
void WriteStringLen(const_data_ptr_t val, idx_t len) {
Write<uint32_t>((uint32_t)len);
if (len > 0) {
WriteData(val, len);
}
}
template <class T>
void WriteList(const vector<unique_ptr<T>> &list) {
Write<uint32_t>((uint32_t)list.size());
for (auto &child : list) {
child->Serialize(*this);
}
}
void WriteStringVector(const vector<string> &list) {
Write<uint32_t>((uint32_t)list.size());
for (auto &child : list) {
WriteString(child);
}
}
template <class T>
void WriteOptional(const unique_ptr<T> &element) {
Write<bool>(element ? true : false);
if (element) {
element->Serialize(*this);
}
}
};
class Deserializer {
private:
uint64_t version = 0L;
public:
virtual ~Deserializer() {
}
void SetVersion(uint64_t v) {
D_ASSERT(this->version == 0); this->version = v;
}
uint64_t GetVersion() {
return version;
}
virtual void ReadData(data_ptr_t buffer, idx_t read_size) = 0;
template <class T>
T Read() {
T value;
ReadData((data_ptr_t)&value, sizeof(T));
return value;
}
template <class T, typename... ARGS>
void ReadList(vector<unique_ptr<T>> &list, ARGS &&... args) {
auto select_count = Read<uint32_t>();
for (uint32_t i = 0; i < select_count; i++) {
auto child = T::Deserialize(*this, std::forward<ARGS>(args)...);
list.push_back(std::move(child));
}
}
template <class T, class RETURN_TYPE = T, typename... ARGS>
unique_ptr<RETURN_TYPE> ReadOptional(ARGS &&... args) {
auto has_entry = Read<bool>();
if (has_entry) {
return T::Deserialize(*this, std::forward<ARGS>(args)...);
}
return nullptr;
}
void ReadStringVector(vector<string> &list);
};
template <>
DUCKDB_API string Deserializer::Read();
}
namespace duckdb {
enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZIP = 2, ZSTD = 3 };
FileCompressionType FileCompressionTypeFromString(const string &input);
}
namespace duckdb {
class Allocator;
struct FileHandle;
enum class FileBufferType : uint8_t { BLOCK = 1, MANAGED_BUFFER = 2, TINY_BUFFER = 3 };
class FileBuffer {
public:
FileBuffer(Allocator &allocator, FileBufferType type, uint64_t user_size);
FileBuffer(FileBuffer &source, FileBufferType type);
virtual ~FileBuffer();
Allocator &allocator;
FileBufferType type;
data_ptr_t buffer;
uint64_t size;
public:
void Read(FileHandle &handle, uint64_t location);
void Write(FileHandle &handle, uint64_t location);
void Clear();
void Resize(uint64_t user_size);
uint64_t AllocSize() const {
return internal_size;
}
data_ptr_t InternalBuffer() {
return internal_buffer;
}
struct MemoryRequirement {
idx_t alloc_size;
idx_t header_size;
};
MemoryRequirement CalculateMemory(uint64_t user_size);
protected:
data_ptr_t internal_buffer;
uint64_t internal_size;
void ReallocBuffer(size_t malloc_size);
void Init();
};
}
#include <unordered_map>
namespace duckdb {
using std::unordered_map;
}
#include <functional>
#undef CreateDirectory
#undef MoveFile
#undef RemoveDirectory
namespace duckdb {
class AttachedDatabase;
class ClientContext;
class DatabaseInstance;
class FileOpener;
class FileSystem;
enum class FileType {
FILE_TYPE_REGULAR,
FILE_TYPE_DIR,
FILE_TYPE_FIFO,
FILE_TYPE_SOCKET,
FILE_TYPE_LINK,
FILE_TYPE_BLOCKDEV,
FILE_TYPE_CHARDEV,
FILE_TYPE_INVALID,
};
struct FileHandle {
public:
DUCKDB_API FileHandle(FileSystem &file_system, string path);
FileHandle(const FileHandle &) = delete;
DUCKDB_API virtual ~FileHandle();
DUCKDB_API int64_t Read(void *buffer, idx_t nr_bytes);
DUCKDB_API int64_t Write(void *buffer, idx_t nr_bytes);
DUCKDB_API void Read(void *buffer, idx_t nr_bytes, idx_t location);
DUCKDB_API void Write(void *buffer, idx_t nr_bytes, idx_t location);
DUCKDB_API void Seek(idx_t location);
DUCKDB_API void Reset();
DUCKDB_API idx_t SeekPosition();
DUCKDB_API void Sync();
DUCKDB_API void Truncate(int64_t new_size);
DUCKDB_API string ReadLine();
DUCKDB_API bool CanSeek();
DUCKDB_API bool OnDiskFile();
DUCKDB_API idx_t GetFileSize();
DUCKDB_API FileType GetType();
DUCKDB_API virtual void Close() = 0;
string GetPath() const {
return path;
}
public:
FileSystem &file_system;
string path;
};
enum class FileLockType : uint8_t { NO_LOCK = 0, READ_LOCK = 1, WRITE_LOCK = 2 };
class FileFlags {
public:
static constexpr uint8_t FILE_FLAGS_READ = 1 << 0;
static constexpr uint8_t FILE_FLAGS_WRITE = 1 << 1;
static constexpr uint8_t FILE_FLAGS_DIRECT_IO = 1 << 2;
static constexpr uint8_t FILE_FLAGS_FILE_CREATE = 1 << 3;
static constexpr uint8_t FILE_FLAGS_FILE_CREATE_NEW = 1 << 4;
static constexpr uint8_t FILE_FLAGS_APPEND = 1 << 5;
};
class FileSystem {
public:
DUCKDB_API virtual ~FileSystem();
public:
DUCKDB_API static constexpr FileLockType DEFAULT_LOCK = FileLockType::NO_LOCK;
DUCKDB_API static constexpr FileCompressionType DEFAULT_COMPRESSION = FileCompressionType::UNCOMPRESSED;
DUCKDB_API static FileSystem &GetFileSystem(ClientContext &context);
DUCKDB_API static FileSystem &GetFileSystem(DatabaseInstance &db);
DUCKDB_API static FileSystem &Get(AttachedDatabase &db);
DUCKDB_API static FileOpener *GetFileOpener(ClientContext &context);
DUCKDB_API virtual unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags,
FileLockType lock = DEFAULT_LOCK,
FileCompressionType compression = DEFAULT_COMPRESSION,
FileOpener *opener = nullptr);
DUCKDB_API virtual void Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location);
DUCKDB_API virtual void Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location);
DUCKDB_API virtual int64_t Read(FileHandle &handle, void *buffer, int64_t nr_bytes);
DUCKDB_API virtual int64_t Write(FileHandle &handle, void *buffer, int64_t nr_bytes);
DUCKDB_API string GetFileExtension(FileHandle &handle);
DUCKDB_API virtual int64_t GetFileSize(FileHandle &handle);
DUCKDB_API virtual time_t GetLastModifiedTime(FileHandle &handle);
DUCKDB_API virtual FileType GetFileType(FileHandle &handle);
DUCKDB_API virtual void Truncate(FileHandle &handle, int64_t new_size);
DUCKDB_API virtual bool DirectoryExists(const string &directory);
DUCKDB_API virtual void CreateDirectory(const string &directory);
DUCKDB_API virtual void RemoveDirectory(const string &directory);
DUCKDB_API virtual bool ListFiles(const string &directory,
const std::function<void(const string &, bool)> &callback,
FileOpener *opener = nullptr);
DUCKDB_API virtual void MoveFile(const string &source, const string &target);
DUCKDB_API virtual bool FileExists(const string &filename);
DUCKDB_API virtual bool IsPipe(const string &filename);
DUCKDB_API virtual void RemoveFile(const string &filename);
DUCKDB_API virtual void FileSync(FileHandle &handle);
DUCKDB_API static void SetWorkingDirectory(const string &path);
DUCKDB_API static string GetWorkingDirectory();
DUCKDB_API static string GetHomeDirectory(FileOpener *opener);
DUCKDB_API static string ExpandPath(const string &path, FileOpener *opener);
DUCKDB_API static idx_t GetAvailableMemory();
DUCKDB_API static string PathSeparator();
DUCKDB_API static bool IsPathAbsolute(const string &path);
DUCKDB_API static string JoinPath(const string &a, const string &path);
DUCKDB_API static string ConvertSeparators(const string &path);
DUCKDB_API static string ExtractBaseName(const string &path);
DUCKDB_API static string ExtractName(const string &path);
DUCKDB_API virtual vector<string> Glob(const string &path, FileOpener *opener = nullptr);
DUCKDB_API virtual vector<string> Glob(const string &path, ClientContext &context);
DUCKDB_API vector<string> GlobFiles(const string &path, ClientContext &context);
DUCKDB_API virtual void RegisterSubSystem(unique_ptr<FileSystem> sub_fs);
DUCKDB_API virtual void RegisterSubSystem(FileCompressionType compression_type, unique_ptr<FileSystem> fs);
DUCKDB_API virtual void UnregisterSubSystem(const string &name);
DUCKDB_API virtual vector<string> ListSubSystems();
DUCKDB_API virtual bool CanHandleFile(const string &fpath);
DUCKDB_API virtual void Seek(FileHandle &handle, idx_t location);
DUCKDB_API virtual void Reset(FileHandle &handle);
DUCKDB_API virtual idx_t SeekPosition(FileHandle &handle);
DUCKDB_API virtual bool CanSeek();
DUCKDB_API virtual bool OnDiskFile(FileHandle &handle);
DUCKDB_API virtual unique_ptr<FileHandle> OpenCompressedFile(unique_ptr<FileHandle> handle, bool write);
DUCKDB_API static unique_ptr<FileSystem> CreateLocal();
DUCKDB_API virtual std::string GetName() const = 0;
};
}
namespace duckdb {
#define FILE_BUFFER_SIZE 4096
class BufferedFileWriter : public Serializer {
public:
static constexpr uint8_t DEFAULT_OPEN_FLAGS = FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE;
DUCKDB_API BufferedFileWriter(FileSystem &fs, const string &path, uint8_t open_flags = DEFAULT_OPEN_FLAGS,
FileOpener *opener = nullptr);
FileSystem &fs;
string path;
unique_ptr<data_t[]> data;
idx_t offset;
idx_t total_written;
unique_ptr<FileHandle> handle;
public:
DUCKDB_API void WriteData(const_data_ptr_t buffer, uint64_t write_size) override;
DUCKDB_API void Sync();
DUCKDB_API void Flush();
DUCKDB_API int64_t GetFileSize();
DUCKDB_API void Truncate(int64_t size);
DUCKDB_API idx_t GetTotalWritten();
};
}
#include <bitset>
namespace duckdb {
using std::bitset;
}
namespace duckdb {
enum class VectorType : uint8_t {
FLAT_VECTOR, FSST_VECTOR, CONSTANT_VECTOR, DICTIONARY_VECTOR, SEQUENCE_VECTOR };
string VectorTypeToString(VectorType type);
}
namespace duckdb {
#ifndef STANDARD_VECTOR_SIZE
#define STANDARD_VECTOR_SIZE 2048
#endif
#if ((STANDARD_VECTOR_SIZE & (STANDARD_VECTOR_SIZE - 1)) != 0)
#error Vector size should be a power of two
#endif
extern const sel_t ZERO_VECTOR[STANDARD_VECTOR_SIZE];
}
namespace duckdb {
class VectorBuffer;
struct SelectionData {
DUCKDB_API explicit SelectionData(idx_t count);
unique_ptr<sel_t[]> owned_data;
};
struct SelectionVector {
SelectionVector() : sel_vector(nullptr) {
}
explicit SelectionVector(sel_t *sel) {
Initialize(sel);
}
explicit SelectionVector(idx_t count) {
Initialize(count);
}
SelectionVector(idx_t start, idx_t count) {
Initialize(STANDARD_VECTOR_SIZE);
for (idx_t i = 0; i < count; i++) {
set_index(i, start + i);
}
}
SelectionVector(const SelectionVector &sel_vector) {
Initialize(sel_vector);
}
explicit SelectionVector(buffer_ptr<SelectionData> data) {
Initialize(std::move(data));
}
SelectionVector &operator=(SelectionVector &&other) {
sel_vector = other.sel_vector;
other.sel_vector = nullptr;
selection_data = std::move(other.selection_data);
return *this;
}
public:
static idx_t Inverted(const SelectionVector &src, SelectionVector &dst, idx_t source_size, idx_t count) {
idx_t src_idx = 0;
idx_t dst_idx = 0;
for (idx_t i = 0; i < count; i++) {
if (src_idx < source_size && src.get_index(src_idx) == i) {
src_idx++;
continue;
}
dst.set_index(dst_idx++, i);
}
return dst_idx;
}
void Initialize(sel_t *sel) {
selection_data.reset();
sel_vector = sel;
}
void Initialize(idx_t count = STANDARD_VECTOR_SIZE) {
selection_data = make_buffer<SelectionData>(count);
sel_vector = selection_data->owned_data.get();
}
void Initialize(buffer_ptr<SelectionData> data) {
selection_data = std::move(data);
sel_vector = selection_data->owned_data.get();
}
void Initialize(const SelectionVector &other) {
selection_data = other.selection_data;
sel_vector = other.sel_vector;
}
inline void set_index(idx_t idx, idx_t loc) {
sel_vector[idx] = loc;
}
inline void swap(idx_t i, idx_t j) {
sel_t tmp = sel_vector[i];
sel_vector[i] = sel_vector[j];
sel_vector[j] = tmp;
}
inline idx_t get_index(idx_t idx) const {
return sel_vector ? sel_vector[idx] : idx;
}
sel_t *data() {
return sel_vector;
}
const sel_t *data() const {
return sel_vector;
}
buffer_ptr<SelectionData> sel_data() {
return selection_data;
}
buffer_ptr<SelectionData> Slice(const SelectionVector &sel, idx_t count) const;
string ToString(idx_t count = 0) const;
void Print(idx_t count = 0) const;
inline sel_t &operator[](idx_t index) const {
return sel_vector[index];
}
private:
sel_t *sel_vector;
buffer_ptr<SelectionData> selection_data;
};
class OptionalSelection {
public:
explicit inline OptionalSelection(SelectionVector *sel_p) {
Initialize(sel_p);
}
void Initialize(SelectionVector *sel_p) {
sel = sel_p;
if (sel) {
vec.Initialize(sel->data());
sel = &vec;
}
}
inline operator SelectionVector *() {
return sel;
}
inline void Append(idx_t &count, const idx_t idx) {
if (sel) {
sel->set_index(count, idx);
}
++count;
}
inline void Advance(idx_t completed) {
if (sel) {
sel->Initialize(sel->data() + completed);
}
}
private:
SelectionVector *sel;
SelectionVector vec;
};
class ManagedSelection {
public:
explicit inline ManagedSelection(idx_t size, bool initialize = true)
: initialized(initialize), size(size), internal_opt_selvec(nullptr) {
count = 0;
if (!initialized) {
return;
}
sel_vec.Initialize(size);
internal_opt_selvec.Initialize(&sel_vec);
}
public:
bool Initialized() const {
return initialized;
}
void Initialize(idx_t size) {
D_ASSERT(!initialized);
this->size = size;
sel_vec.Initialize(size);
internal_opt_selvec.Initialize(&sel_vec);
initialized = true;
}
inline idx_t operator[](idx_t index) const {
D_ASSERT(index < size);
return sel_vec.get_index(index);
}
inline bool IndexMapsToLocation(idx_t idx, idx_t location) const {
return idx < count && sel_vec.get_index(idx) == location;
}
inline void Append(const idx_t idx) {
internal_opt_selvec.Append(count, idx);
}
inline idx_t Count() const {
return count;
}
inline idx_t Size() const {
return size;
}
inline const SelectionVector &Selection() const {
return sel_vec;
}
inline SelectionVector &Selection() {
return sel_vec;
}
private:
bool initialized = false;
idx_t count;
idx_t size;
SelectionVector sel_vec;
OptionalSelection internal_opt_selvec;
};
}
namespace duckdb {
using std::to_string;
}
namespace duckdb {
struct ValidityMask;
template <typename V>
struct TemplatedValidityData {
static constexpr const int BITS_PER_VALUE = sizeof(V) * 8;
static constexpr const V MAX_ENTRY = ~V(0);
public:
inline explicit TemplatedValidityData(idx_t count) {
auto entry_count = EntryCount(count);
owned_data = unique_ptr<V[]>(new V[entry_count]);
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
owned_data[entry_idx] = MAX_ENTRY;
}
}
inline TemplatedValidityData(const V *validity_mask, idx_t count) {
D_ASSERT(validity_mask);
auto entry_count = EntryCount(count);
owned_data = unique_ptr<V[]>(new V[entry_count]);
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
owned_data[entry_idx] = validity_mask[entry_idx];
}
}
unique_ptr<V[]> owned_data;
public:
static inline idx_t EntryCount(idx_t count) {
return (count + (BITS_PER_VALUE - 1)) / BITS_PER_VALUE;
}
};
using validity_t = uint64_t;
struct ValidityData : TemplatedValidityData<validity_t> {
public:
DUCKDB_API explicit ValidityData(idx_t count);
DUCKDB_API ValidityData(const ValidityMask &original, idx_t count);
};
template <typename V>
struct TemplatedValidityMask {
using ValidityBuffer = TemplatedValidityData<V>;
public:
static constexpr const int BITS_PER_VALUE = ValidityBuffer::BITS_PER_VALUE;
static constexpr const int STANDARD_ENTRY_COUNT = (STANDARD_VECTOR_SIZE + (BITS_PER_VALUE - 1)) / BITS_PER_VALUE;
static constexpr const int STANDARD_MASK_SIZE = STANDARD_ENTRY_COUNT * sizeof(validity_t);
public:
inline TemplatedValidityMask() : validity_mask(nullptr) {
}
inline explicit TemplatedValidityMask(idx_t max_count) {
Initialize(max_count);
}
inline explicit TemplatedValidityMask(V *ptr) : validity_mask(ptr) {
}
inline TemplatedValidityMask(const TemplatedValidityMask &original, idx_t count) {
Copy(original, count);
}
static inline idx_t ValidityMaskSize(idx_t count = STANDARD_VECTOR_SIZE) {
return ValidityBuffer::EntryCount(count) * sizeof(V);
}
inline bool AllValid() const {
return !validity_mask;
}
inline bool CheckAllValid(idx_t count) const {
return CountValid(count) == count;
}
inline bool CheckAllValid(idx_t to, idx_t from) const {
if (AllValid()) {
return true;
}
for (idx_t i = from; i < to; i++) {
if (!RowIsValid(i)) {
return false;
}
}
return true;
}
idx_t CountValid(const idx_t count) const {
if (AllValid() || count == 0) {
return count;
}
idx_t valid = 0;
const auto entry_count = EntryCount(count);
for (idx_t entry_idx = 0; entry_idx < entry_count;) {
auto entry = GetValidityEntry(entry_idx++);
if (entry_idx == entry_count && count % BITS_PER_VALUE != 0) {
idx_t idx_in_entry;
GetEntryIndex(count, entry_idx, idx_in_entry);
for (idx_t i = 0; i < idx_in_entry; ++i) {
valid += idx_t(RowIsValid(entry, i));
}
break;
}
if (AllValid(entry)) {
valid += BITS_PER_VALUE;
continue;
}
while (entry) {
entry &= (entry - 1);
++valid;
}
}
return valid;
}
inline V *GetData() const {
return validity_mask;
}
inline void Reset() {
validity_mask = nullptr;
validity_data.reset();
}
static inline idx_t EntryCount(idx_t count) {
return ValidityBuffer::EntryCount(count);
}
inline V GetValidityEntry(idx_t entry_idx) const {
if (!validity_mask) {
return ValidityBuffer::MAX_ENTRY;
}
return validity_mask[entry_idx];
}
static inline bool AllValid(V entry) {
return entry == ValidityBuffer::MAX_ENTRY;
}
static inline bool NoneValid(V entry) {
return entry == 0;
}
static inline bool RowIsValid(V entry, idx_t idx_in_entry) {
return entry & (V(1) << V(idx_in_entry));
}
static inline void GetEntryIndex(idx_t row_idx, idx_t &entry_idx, idx_t &idx_in_entry) {
entry_idx = row_idx / BITS_PER_VALUE;
idx_in_entry = row_idx % BITS_PER_VALUE;
}
static inline V EntryWithValidBits(idx_t n) {
if (n == 0) {
return V(0);
}
return ValidityBuffer::MAX_ENTRY >> (BITS_PER_VALUE - n);
}
inline bool RowIsValidUnsafe(idx_t row_idx) const {
D_ASSERT(validity_mask);
idx_t entry_idx, idx_in_entry;
GetEntryIndex(row_idx, entry_idx, idx_in_entry);
auto entry = GetValidityEntry(entry_idx);
return RowIsValid(entry, idx_in_entry);
}
inline bool RowIsValid(idx_t row_idx) const {
if (!validity_mask) {
return true;
}
return RowIsValidUnsafe(row_idx);
}
inline void SetValidUnsafe(idx_t row_idx) {
D_ASSERT(validity_mask);
idx_t entry_idx, idx_in_entry;
GetEntryIndex(row_idx, entry_idx, idx_in_entry);
validity_mask[entry_idx] |= (V(1) << V(idx_in_entry));
}
inline void SetValid(idx_t row_idx) {
if (!validity_mask) {
return;
}
SetValidUnsafe(row_idx);
}
inline void SetInvalidUnsafe(idx_t entry_idx, idx_t idx_in_entry) {
D_ASSERT(validity_mask);
validity_mask[entry_idx] &= ~(V(1) << V(idx_in_entry));
}
inline void SetInvalidUnsafe(idx_t row_idx) {
idx_t entry_idx, idx_in_entry;
GetEntryIndex(row_idx, entry_idx, idx_in_entry);
SetInvalidUnsafe(entry_idx, idx_in_entry);
}
inline void SetInvalid(idx_t row_idx) {
if (!validity_mask) {
D_ASSERT(row_idx <= STANDARD_VECTOR_SIZE);
Initialize(STANDARD_VECTOR_SIZE);
}
SetInvalidUnsafe(row_idx);
}
inline void Set(idx_t row_idx, bool valid) {
if (valid) {
SetValid(row_idx);
} else {
SetInvalid(row_idx);
}
}
inline void EnsureWritable() {
if (!validity_mask) {
Initialize();
}
}
inline void SetAllInvalid(idx_t count) {
EnsureWritable();
if (count == 0) {
return;
}
auto last_entry_index = ValidityBuffer::EntryCount(count) - 1;
for (idx_t i = 0; i < last_entry_index; i++) {
validity_mask[i] = 0;
}
auto last_entry_bits = count % static_cast<idx_t>(BITS_PER_VALUE);
validity_mask[last_entry_index] = (last_entry_bits == 0) ? 0 : (ValidityBuffer::MAX_ENTRY << (last_entry_bits));
}
inline void SetAllValid(idx_t count) {
EnsureWritable();
if (count == 0) {
return;
}
auto last_entry_index = ValidityBuffer::EntryCount(count) - 1;
for (idx_t i = 0; i < last_entry_index; i++) {
validity_mask[i] = ValidityBuffer::MAX_ENTRY;
}
auto last_entry_bits = count % static_cast<idx_t>(BITS_PER_VALUE);
validity_mask[last_entry_index] |=
(last_entry_bits == 0) ? ValidityBuffer::MAX_ENTRY : ~(ValidityBuffer::MAX_ENTRY << (last_entry_bits));
}
inline bool IsMaskSet() const {
if (validity_mask) {
return true;
}
return false;
}
public:
inline void Initialize(validity_t *validity) {
validity_data.reset();
validity_mask = validity;
}
inline void Initialize(const TemplatedValidityMask &other) {
validity_mask = other.validity_mask;
validity_data = other.validity_data;
}
inline void Initialize(idx_t count = STANDARD_VECTOR_SIZE) {
validity_data = make_buffer<ValidityBuffer>(count);
validity_mask = validity_data->owned_data.get();
}
inline void Copy(const TemplatedValidityMask &other, idx_t count) {
if (other.AllValid()) {
validity_data = nullptr;
validity_mask = nullptr;
} else {
validity_data = make_buffer<ValidityBuffer>(other.validity_mask, count);
validity_mask = validity_data->owned_data.get();
}
}
protected:
V *validity_mask;
buffer_ptr<ValidityBuffer> validity_data;
};
struct ValidityMask : public TemplatedValidityMask<validity_t> {
public:
inline ValidityMask() : TemplatedValidityMask(nullptr) {
}
inline explicit ValidityMask(idx_t max_count) : TemplatedValidityMask(max_count) {
}
inline explicit ValidityMask(validity_t *ptr) : TemplatedValidityMask(ptr) {
}
inline ValidityMask(const ValidityMask &original, idx_t count) : TemplatedValidityMask(original, count) {
}
public:
DUCKDB_API void Resize(idx_t old_size, idx_t new_size);
DUCKDB_API void Slice(const ValidityMask &other, idx_t offset, idx_t end);
DUCKDB_API void Combine(const ValidityMask &other, idx_t count);
DUCKDB_API string ToString(idx_t count) const;
};
}
#undef max
#include <limits>
namespace duckdb {
template <class T>
struct NumericLimits {
DUCKDB_API static constexpr T Minimum() {
return std::numeric_limits<T>::lowest();
};
DUCKDB_API static constexpr T Maximum() {
return std::numeric_limits<T>::max();
};
DUCKDB_API static bool IsSigned();
DUCKDB_API static idx_t Digits();
};
template <>
struct NumericLimits<int8_t> {
DUCKDB_API static constexpr int8_t Minimum() {
return std::numeric_limits<int8_t>::lowest();
};
DUCKDB_API static constexpr int8_t Maximum() {
return std::numeric_limits<int8_t>::max();
};
DUCKDB_API static bool IsSigned() {
return true;
}
DUCKDB_API static idx_t Digits() {
return 3;
}
};
template <>
struct NumericLimits<int16_t> {
DUCKDB_API static constexpr int16_t Minimum() {
return std::numeric_limits<int16_t>::lowest();
};
DUCKDB_API static constexpr int16_t Maximum() {
return std::numeric_limits<int16_t>::max();
};
DUCKDB_API static bool IsSigned() {
return true;
}
DUCKDB_API static idx_t Digits() {
return 5;
}
};
template <>
struct NumericLimits<int32_t> {
DUCKDB_API static constexpr int32_t Minimum() {
return std::numeric_limits<int32_t>::lowest();
};
DUCKDB_API static constexpr int32_t Maximum() {
return std::numeric_limits<int32_t>::max();
};
DUCKDB_API static bool IsSigned() {
return true;
}
DUCKDB_API static idx_t Digits() {
return 10;
}
};
template <>
struct NumericLimits<int64_t> {
DUCKDB_API static constexpr int64_t Minimum() {
return std::numeric_limits<int64_t>::lowest();
};
DUCKDB_API static constexpr int64_t Maximum() {
return std::numeric_limits<int64_t>::max();
};
DUCKDB_API static bool IsSigned() {
return true;
}
DUCKDB_API static idx_t Digits() {
return 19;
}
};
template <>
struct NumericLimits<hugeint_t> {
DUCKDB_API static constexpr hugeint_t Minimum() {
return {std::numeric_limits<int64_t>::lowest(), 1};
};
DUCKDB_API static constexpr hugeint_t Maximum() {
return {std::numeric_limits<int64_t>::max(), std::numeric_limits<uint64_t>::max()};
};
DUCKDB_API static bool IsSigned() {
return true;
}
DUCKDB_API static idx_t Digits() {
return 39;
}
};
template <>
struct NumericLimits<uint8_t> {
DUCKDB_API static constexpr uint8_t Minimum() {
return std::numeric_limits<uint8_t>::lowest();
};
DUCKDB_API static constexpr uint8_t Maximum() {
return std::numeric_limits<uint8_t>::max();
};
DUCKDB_API static bool IsSigned() {
return false;
}
DUCKDB_API static idx_t Digits() {
return 3;
}
};
template <>
struct NumericLimits<uint16_t> {
DUCKDB_API static constexpr uint16_t Minimum() {
return std::numeric_limits<uint16_t>::lowest();
};
DUCKDB_API static constexpr uint16_t Maximum() {
return std::numeric_limits<uint16_t>::max();
};
DUCKDB_API static bool IsSigned() {
return false;
}
DUCKDB_API static idx_t Digits() {
return 5;
}
};
template <>
struct NumericLimits<uint32_t> {
DUCKDB_API static constexpr uint32_t Minimum() {
return std::numeric_limits<uint32_t>::lowest();
};
DUCKDB_API static constexpr uint32_t Maximum() {
return std::numeric_limits<uint32_t>::max();
};
DUCKDB_API static bool IsSigned() {
return false;
}
DUCKDB_API static idx_t Digits() {
return 10;
}
};
template <>
struct NumericLimits<uint64_t> {
DUCKDB_API static constexpr uint64_t Minimum() {
return std::numeric_limits<uint64_t>::lowest();
};
DUCKDB_API static constexpr uint64_t Maximum() {
return std::numeric_limits<uint64_t>::max();
};
DUCKDB_API static bool IsSigned() {
return false;
}
DUCKDB_API static idx_t Digits() {
return 20;
}
};
template <>
struct NumericLimits<float> {
DUCKDB_API static constexpr float Minimum() {
return std::numeric_limits<float>::lowest();
};
DUCKDB_API static constexpr float Maximum() {
return std::numeric_limits<float>::max();
};
DUCKDB_API static bool IsSigned() {
return true;
}
DUCKDB_API static idx_t Digits() {
return 127;
}
};
template <>
struct NumericLimits<double> {
DUCKDB_API static constexpr double Minimum() {
return std::numeric_limits<double>::lowest();
};
DUCKDB_API static constexpr double Maximum() {
return std::numeric_limits<double>::max();
};
DUCKDB_API static bool IsSigned() {
return true;
}
DUCKDB_API static idx_t Digits() {
return 250;
}
};
}
namespace duckdb {
class StringUtil {
public:
DUCKDB_API static bool CharacterIsSpace(char c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
}
DUCKDB_API static bool CharacterIsNewline(char c) {
return c == '\n' || c == '\r';
}
DUCKDB_API static bool CharacterIsDigit(char c) {
return c >= '0' && c <= '9';
}
DUCKDB_API static bool CharacterIsHex(char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
DUCKDB_API static char CharacterToLower(char c) {
if (c >= 'A' && c <= 'Z') {
return c - ('A' - 'a');
}
return c;
}
DUCKDB_API static char CharacterIsAlpha(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
static bool CharacterIsOperator(char c) {
if (c == '_') {
return false;
}
if (c >= '!' && c <= '/') {
return true;
}
if (c >= ':' && c <= '@') {
return true;
}
if (c >= '[' && c <= '`') {
return true;
}
if (c >= '{' && c <= '~') {
return true;
}
return false;
}
DUCKDB_API static bool Contains(const string &haystack, const string &needle);
DUCKDB_API static bool StartsWith(string str, string prefix);
DUCKDB_API static bool EndsWith(const string &str, const string &suffix);
DUCKDB_API static string Repeat(const string &str, const idx_t n);
DUCKDB_API static vector<string> Split(const string &str, char delimiter);
DUCKDB_API static vector<string> SplitWithQuote(const string &str, char delimiter = ',', char quote = '"');
DUCKDB_API static string Join(const vector<string> &input, const string &separator);
template <class T>
static string ToString(const vector<T> &input, const string &separator) {
vector<string> input_list;
for (auto &i : input) {
input_list.push_back(i.ToString());
}
return StringUtil::Join(input_list, separator);
}
template <typename C, typename S, typename Func>
static string Join(const C &input, S count, const string &separator, Func f) {
std::string result;
if (count > 0) {
result += f(input[0]);
}
for (size_t i = 1; i < count; i++) {
result += separator + f(input[i]);
}
return result;
}
DUCKDB_API static string BytesToHumanReadableString(idx_t bytes);
DUCKDB_API static string Upper(const string &str);
DUCKDB_API static string Lower(const string &str);
DUCKDB_API static bool CIEquals(const string &l1, const string &l2);
template <typename... Args>
static string Format(const string fmt_str, Args... params) {
return Exception::ConstructMessage(fmt_str, params...);
}
DUCKDB_API static vector<string> Split(const string &input, const string &split);
DUCKDB_API static void LTrim(string &str);
DUCKDB_API static void RTrim(string &str);
DUCKDB_API static void RTrim(string &str, const string &chars_to_trim);
DUCKDB_API static void Trim(string &str);
DUCKDB_API static string Replace(string source, const string &from, const string &to);
DUCKDB_API static idx_t LevenshteinDistance(const string &s1, const string &s2, idx_t not_equal_penalty = 1);
DUCKDB_API static idx_t SimilarityScore(const string &s1, const string &s2);
DUCKDB_API static vector<string> TopNStrings(vector<std::pair<string, idx_t>> scores, idx_t n = 5,
idx_t threshold = 5);
DUCKDB_API static vector<string> TopNLevenshtein(const vector<string> &strings, const string &target, idx_t n = 5,
idx_t threshold = 5);
DUCKDB_API static string CandidatesMessage(const vector<string> &candidates,
const string &candidate = "Candidate bindings");
DUCKDB_API static string CandidatesErrorMessage(const vector<string> &strings, const string &target,
const string &message_prefix, idx_t n = 5);
};
}
#include <functional>
namespace duckdb {
struct date_t;
struct dtime_t;
struct timestamp_t { int64_t value;
timestamp_t() = default;
explicit inline timestamp_t(int64_t value_p) : value(value_p) {
}
inline timestamp_t &operator=(int64_t value_p) {
value = value_p;
return *this;
}
explicit inline operator int64_t() const {
return value;
}
inline bool operator==(const timestamp_t &rhs) const {
return value == rhs.value;
};
inline bool operator!=(const timestamp_t &rhs) const {
return value != rhs.value;
};
inline bool operator<=(const timestamp_t &rhs) const {
return value <= rhs.value;
};
inline bool operator<(const timestamp_t &rhs) const {
return value < rhs.value;
};
inline bool operator>(const timestamp_t &rhs) const {
return value > rhs.value;
};
inline bool operator>=(const timestamp_t &rhs) const {
return value >= rhs.value;
};
inline timestamp_t operator+(const double &value) const {
return timestamp_t(this->value + int64_t(value));
};
inline int64_t operator-(const timestamp_t &other) const {
return this->value - other.value;
};
inline timestamp_t &operator+=(const int64_t &value) {
this->value += value;
return *this;
};
inline timestamp_t &operator-=(const int64_t &value) {
this->value -= value;
return *this;
};
static timestamp_t infinity() { return timestamp_t(NumericLimits<int64_t>::Maximum());
} static timestamp_t ninfinity() { return timestamp_t(-NumericLimits<int64_t>::Maximum());
} static inline timestamp_t epoch() { return timestamp_t(0);
} };
struct timestamp_tz_t : public timestamp_t {}; struct timestamp_ns_t : public timestamp_t {}; struct timestamp_ms_t : public timestamp_t {}; struct timestamp_sec_t : public timestamp_t {};
enum class TimestampCastResult : uint8_t { SUCCESS, ERROR_INCORRECT_FORMAT, ERROR_NON_UTC_TIMEZONE };
class Timestamp {
public:
constexpr static const int32_t MIN_YEAR = -290308;
constexpr static const int32_t MIN_MONTH = 12;
constexpr static const int32_t MIN_DAY = 22;
public:
DUCKDB_API static timestamp_t FromString(const string &str);
DUCKDB_API static bool TryConvertTimestampTZ(const char *str, idx_t len, timestamp_t &result, bool &has_offset,
string_t &tz);
DUCKDB_API static TimestampCastResult TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result);
DUCKDB_API static timestamp_t FromCString(const char *str, idx_t len);
DUCKDB_API static string ToString(timestamp_t timestamp);
DUCKDB_API static date_t GetDate(timestamp_t timestamp);
DUCKDB_API static dtime_t GetTime(timestamp_t timestamp);
DUCKDB_API static timestamp_t FromDatetime(date_t date, dtime_t time);
DUCKDB_API static bool TryFromDatetime(date_t date, dtime_t time, timestamp_t &result);
static inline bool CharacterIsTimeZone(char c) {
return StringUtil::CharacterIsAlpha(c) || StringUtil::CharacterIsDigit(c) || c == '_' || c == '/' || c == '+' ||
c == '-';
}
static inline bool IsFinite(timestamp_t timestamp) {
return timestamp != timestamp_t::infinity() && timestamp != timestamp_t::ninfinity();
}
DUCKDB_API static void Convert(timestamp_t date, date_t &out_date, dtime_t &out_time);
DUCKDB_API static timestamp_t GetCurrentTimestamp();
DUCKDB_API static timestamp_t FromEpochSeconds(int64_t ms);
DUCKDB_API static timestamp_t FromEpochMs(int64_t ms);
DUCKDB_API static timestamp_t FromEpochMicroSeconds(int64_t micros);
DUCKDB_API static timestamp_t FromEpochNanoSeconds(int64_t micros);
DUCKDB_API static int64_t GetEpochSeconds(timestamp_t timestamp);
DUCKDB_API static int64_t GetEpochMs(timestamp_t timestamp);
DUCKDB_API static int64_t GetEpochMicroSeconds(timestamp_t timestamp);
DUCKDB_API static int64_t GetEpochNanoSeconds(timestamp_t timestamp);
DUCKDB_API static bool TryParseUTCOffset(const char *str, idx_t &pos, idx_t len, int &hour_offset,
int &minute_offset);
DUCKDB_API static string ConversionError(const string &str);
DUCKDB_API static string ConversionError(string_t str);
DUCKDB_API static string UnsupportedTimezoneError(const string &str);
DUCKDB_API static string UnsupportedTimezoneError(string_t str);
};
}
namespace std {
template <>
struct hash<duckdb::timestamp_t> {
std::size_t operator()(const duckdb::timestamp_t &k) const {
using std::hash;
return hash<int64_t>()((int64_t)k);
}
};
template <>
struct hash<duckdb::timestamp_ms_t> {
std::size_t operator()(const duckdb::timestamp_ms_t &k) const {
using std::hash;
return hash<int64_t>()((int64_t)k);
}
};
template <>
struct hash<duckdb::timestamp_ns_t> {
std::size_t operator()(const duckdb::timestamp_ns_t &k) const {
using std::hash;
return hash<int64_t>()((int64_t)k);
}
};
template <>
struct hash<duckdb::timestamp_sec_t> {
std::size_t operator()(const duckdb::timestamp_sec_t &k) const {
using std::hash;
return hash<int64_t>()((int64_t)k);
}
};
template <>
struct hash<duckdb::timestamp_tz_t> {
std::size_t operator()(const duckdb::timestamp_tz_t &k) const {
using std::hash;
return hash<int64_t>()((int64_t)k);
}
};
}
#include <cstring>
namespace duckdb {
struct string_t {
friend struct StringComparisonOperators;
friend class StringSegment;
public:
static constexpr idx_t PREFIX_BYTES = 4 * sizeof(char);
static constexpr idx_t INLINE_BYTES = 12 * sizeof(char);
static constexpr idx_t HEADER_SIZE = sizeof(uint32_t) + PREFIX_BYTES;
#ifndef DUCKDB_DEBUG_NO_INLINE
static constexpr idx_t PREFIX_LENGTH = PREFIX_BYTES;
static constexpr idx_t INLINE_LENGTH = INLINE_BYTES;
#else
static constexpr idx_t PREFIX_LENGTH = 0;
static constexpr idx_t INLINE_LENGTH = 0;
#endif
string_t() = default;
explicit string_t(uint32_t len) {
value.inlined.length = len;
}
string_t(const char *data, uint32_t len) {
value.inlined.length = len;
D_ASSERT(data || GetSize() == 0);
if (IsInlined()) {
memset(value.inlined.inlined, 0, INLINE_BYTES);
if (GetSize() == 0) {
return;
}
memcpy(value.inlined.inlined, data, GetSize());
} else {
#ifndef DUCKDB_DEBUG_NO_INLINE
memcpy(value.pointer.prefix, data, PREFIX_LENGTH);
#else
memset(value.pointer.prefix, 0, PREFIX_BYTES);
#endif
value.pointer.ptr = (char *)data;
}
}
string_t(const char *data) : string_t(data, strlen(data)) { }
string_t(const string &value)
: string_t(value.c_str(), value.size()) { }
bool IsInlined() const {
return GetSize() <= INLINE_LENGTH;
}
const char *GetDataUnsafe() const {
return IsInlined() ? (const char *)value.inlined.inlined : value.pointer.ptr;
}
char *GetDataWriteable() const {
return IsInlined() ? (char *)value.inlined.inlined : value.pointer.ptr;
}
const char *GetPrefix() const {
return value.pointer.prefix;
}
idx_t GetSize() const {
return value.inlined.length;
}
string GetString() const {
return string(GetDataUnsafe(), GetSize());
}
explicit operator string() const {
return GetString();
}
void SetPointer(char *new_ptr) {
D_ASSERT(!IsInlined());
value.pointer.ptr = new_ptr;
}
void Finalize() {
if (GetSize() <= INLINE_LENGTH) {
for (idx_t i = GetSize(); i < INLINE_BYTES; i++) {
value.inlined.inlined[i] = '\0';
}
} else {
#ifndef DUCKDB_DEBUG_NO_INLINE
auto dataptr = (char *)GetDataUnsafe();
memcpy(value.pointer.prefix, dataptr, PREFIX_LENGTH);
#else
memset(value.pointer.prefix, 0, PREFIX_BYTES);
#endif
}
}
void Verify() const;
void VerifyNull() const;
bool operator<(const string_t &r) const {
auto this_str = this->GetString();
auto r_str = r.GetString();
return this_str < r_str;
}
private:
union {
struct {
uint32_t length;
char prefix[4];
char *ptr;
} pointer;
struct {
uint32_t length;
char inlined[12];
} inlined;
} value;
};
}
#include <functional>
namespace duckdb {
struct timestamp_t;
struct date_t { int32_t days;
date_t() = default;
explicit inline date_t(int32_t days_p) : days(days_p) {
}
explicit inline operator int32_t() const {
return days;
}
inline bool operator==(const date_t &rhs) const {
return days == rhs.days;
};
inline bool operator!=(const date_t &rhs) const {
return days != rhs.days;
};
inline bool operator<=(const date_t &rhs) const {
return days <= rhs.days;
};
inline bool operator<(const date_t &rhs) const {
return days < rhs.days;
};
inline bool operator>(const date_t &rhs) const {
return days > rhs.days;
};
inline bool operator>=(const date_t &rhs) const {
return days >= rhs.days;
};
inline date_t operator+(const int32_t &days) const {
return date_t(this->days + days);
};
inline date_t operator-(const int32_t &days) const {
return date_t(this->days - days);
};
inline date_t &operator+=(const int32_t &days) {
this->days += days;
return *this;
};
inline date_t &operator-=(const int32_t &days) {
this->days -= days;
return *this;
};
static inline date_t infinity() {
return date_t(NumericLimits<int32_t>::Maximum());
} static inline date_t ninfinity() {
return date_t(-NumericLimits<int32_t>::Maximum());
} static inline date_t epoch() {
return date_t(0);
} };
class Date {
public:
static const char *PINF; static const char *NINF; static const char *EPOCH;
static const string_t MONTH_NAMES[12];
static const string_t MONTH_NAMES_ABBREVIATED[12];
static const string_t DAY_NAMES[7];
static const string_t DAY_NAMES_ABBREVIATED[7];
static const int32_t NORMAL_DAYS[13];
static const int32_t CUMULATIVE_DAYS[13];
static const int32_t LEAP_DAYS[13];
static const int32_t CUMULATIVE_LEAP_DAYS[13];
static const int32_t CUMULATIVE_YEAR_DAYS[401];
static const int8_t MONTH_PER_DAY_OF_YEAR[365];
static const int8_t LEAP_MONTH_PER_DAY_OF_YEAR[366];
constexpr static const int32_t DATE_MIN_YEAR = -5877641;
constexpr static const int32_t DATE_MIN_MONTH = 6;
constexpr static const int32_t DATE_MIN_DAY = 25;
constexpr static const int32_t DATE_MAX_YEAR = 5881580;
constexpr static const int32_t DATE_MAX_MONTH = 7;
constexpr static const int32_t DATE_MAX_DAY = 10;
constexpr static const int32_t EPOCH_YEAR = 1970;
constexpr static const int32_t YEAR_INTERVAL = 400;
constexpr static const int32_t DAYS_PER_YEAR_INTERVAL = 146097;
public:
DUCKDB_API static date_t FromString(const string &str, bool strict = false);
DUCKDB_API static date_t FromCString(const char *str, idx_t len, bool strict = false);
DUCKDB_API static string ToString(date_t date);
DUCKDB_API static bool TryConvertDate(const char *buf, idx_t len, idx_t &pos, date_t &result, bool &special,
bool strict = false);
DUCKDB_API static string Format(int32_t year, int32_t month, int32_t day);
DUCKDB_API static void Convert(date_t date, int32_t &out_year, int32_t &out_month, int32_t &out_day);
DUCKDB_API static date_t FromDate(int32_t year, int32_t month, int32_t day);
DUCKDB_API static bool TryFromDate(int32_t year, int32_t month, int32_t day, date_t &result);
DUCKDB_API static bool IsLeapYear(int32_t year);
DUCKDB_API static bool IsValid(int32_t year, int32_t month, int32_t day);
static inline bool IsFinite(date_t date) {
return date != date_t::infinity() && date != date_t::ninfinity();
}
DUCKDB_API static int32_t MonthDays(int32_t year, int32_t month);
DUCKDB_API static int64_t Epoch(date_t date);
DUCKDB_API static int64_t EpochNanoseconds(date_t date);
DUCKDB_API static int64_t EpochMicroseconds(date_t date);
DUCKDB_API static date_t EpochToDate(int64_t epoch);
DUCKDB_API static int32_t EpochDays(date_t date);
DUCKDB_API static date_t EpochDaysToDate(int32_t epoch);
DUCKDB_API static int32_t ExtractYear(date_t date);
DUCKDB_API static int32_t ExtractYear(date_t date, int32_t *last_year);
DUCKDB_API static int32_t ExtractYear(timestamp_t ts, int32_t *last_year);
DUCKDB_API static int32_t ExtractMonth(date_t date);
DUCKDB_API static int32_t ExtractDay(date_t date);
DUCKDB_API static int32_t ExtractISODayOfTheWeek(date_t date);
DUCKDB_API static int32_t ExtractDayOfTheYear(date_t date);
DUCKDB_API static void ExtractISOYearWeek(date_t date, int32_t &year, int32_t &week);
DUCKDB_API static int32_t ExtractISOWeekNumber(date_t date);
DUCKDB_API static int32_t ExtractISOYearNumber(date_t date);
DUCKDB_API static int32_t ExtractWeekNumberRegular(date_t date, bool monday_first = true);
DUCKDB_API static date_t GetMondayOfCurrentWeek(date_t date);
DUCKDB_API static bool ParseDoubleDigit(const char *buf, idx_t len, idx_t &pos, int32_t &result);
DUCKDB_API static string ConversionError(const string &str);
DUCKDB_API static string ConversionError(string_t str);
private:
static void ExtractYearOffset(int32_t &n, int32_t &year, int32_t &year_offset);
};
}
namespace std {
template <>
struct hash<duckdb::date_t> {
std::size_t operator()(const duckdb::date_t &k) const {
using std::hash;
return hash<int32_t>()((int32_t)k);
}
};
}
#include <functional>
namespace duckdb {
struct dtime_t { int64_t micros;
dtime_t() = default;
explicit inline dtime_t(int64_t micros_p) : micros(micros_p) {
}
inline dtime_t &operator=(int64_t micros_p) {
micros = micros_p;
return *this;
}
explicit inline operator int64_t() const {
return micros;
}
explicit inline operator double() const {
return micros;
}
inline bool operator==(const dtime_t &rhs) const {
return micros == rhs.micros;
};
inline bool operator!=(const dtime_t &rhs) const {
return micros != rhs.micros;
};
inline bool operator<=(const dtime_t &rhs) const {
return micros <= rhs.micros;
};
inline bool operator<(const dtime_t &rhs) const {
return micros < rhs.micros;
};
inline bool operator>(const dtime_t &rhs) const {
return micros > rhs.micros;
};
inline bool operator>=(const dtime_t &rhs) const {
return micros >= rhs.micros;
};
inline dtime_t operator+(const int64_t µs) const {
return dtime_t(this->micros + micros);
};
inline dtime_t operator+(const double µs) const {
return dtime_t(this->micros + int64_t(micros));
};
inline dtime_t operator-(const int64_t µs) const {
return dtime_t(this->micros - micros);
};
inline dtime_t operator*(const idx_t &copies) const {
return dtime_t(this->micros * copies);
};
inline dtime_t operator/(const idx_t &copies) const {
return dtime_t(this->micros / copies);
};
inline int64_t operator-(const dtime_t &other) const {
return this->micros - other.micros;
};
inline dtime_t &operator+=(const int64_t µs) {
this->micros += micros;
return *this;
};
inline dtime_t &operator-=(const int64_t µs) {
this->micros -= micros;
return *this;
};
inline dtime_t &operator+=(const dtime_t &other) {
this->micros += other.micros;
return *this;
};
static inline dtime_t allballs() {
return dtime_t(0);
} };
struct dtime_tz_t : public dtime_t {};
}
namespace std {
template <>
struct hash<duckdb::dtime_t> {
std::size_t operator()(const duckdb::dtime_t &k) const {
using std::hash;
return hash<int64_t>()((int64_t)k);
}
};
template <>
struct hash<duckdb::dtime_tz_t> {
std::size_t operator()(const duckdb::dtime_tz_t &k) const {
using std::hash;
return hash<int64_t>()((int64_t)k);
}
};
}
namespace duckdb {
struct dtime_t;
struct date_t;
struct timestamp_t;
struct interval_t {
int32_t months;
int32_t days;
int64_t micros;
inline bool operator==(const interval_t &rhs) const {
return this->days == rhs.days && this->months == rhs.months && this->micros == rhs.micros;
}
};
class Interval {
public:
static constexpr const int32_t MONTHS_PER_MILLENIUM = 12000;
static constexpr const int32_t MONTHS_PER_CENTURY = 1200;
static constexpr const int32_t MONTHS_PER_DECADE = 120;
static constexpr const int32_t MONTHS_PER_YEAR = 12;
static constexpr const int32_t MONTHS_PER_QUARTER = 3;
static constexpr const int32_t DAYS_PER_WEEK = 7;
static constexpr const int64_t DAYS_PER_MONTH = 30;
static constexpr const int64_t DAYS_PER_YEAR = 365;
static constexpr const int64_t MSECS_PER_SEC = 1000;
static constexpr const int32_t SECS_PER_MINUTE = 60;
static constexpr const int32_t MINS_PER_HOUR = 60;
static constexpr const int32_t HOURS_PER_DAY = 24;
static constexpr const int32_t SECS_PER_HOUR = SECS_PER_MINUTE * MINS_PER_HOUR;
static constexpr const int32_t SECS_PER_DAY = SECS_PER_HOUR * HOURS_PER_DAY;
static constexpr const int32_t SECS_PER_WEEK = SECS_PER_DAY * DAYS_PER_WEEK;
static constexpr const int64_t MICROS_PER_MSEC = 1000;
static constexpr const int64_t MICROS_PER_SEC = MICROS_PER_MSEC * MSECS_PER_SEC;
static constexpr const int64_t MICROS_PER_MINUTE = MICROS_PER_SEC * SECS_PER_MINUTE;
static constexpr const int64_t MICROS_PER_HOUR = MICROS_PER_MINUTE * MINS_PER_HOUR;
static constexpr const int64_t MICROS_PER_DAY = MICROS_PER_HOUR * HOURS_PER_DAY;
static constexpr const int64_t MICROS_PER_WEEK = MICROS_PER_DAY * DAYS_PER_WEEK;
static constexpr const int64_t MICROS_PER_MONTH = MICROS_PER_DAY * DAYS_PER_MONTH;
static constexpr const int64_t NANOS_PER_MICRO = 1000;
static constexpr const int64_t NANOS_PER_MSEC = NANOS_PER_MICRO * MICROS_PER_MSEC;
static constexpr const int64_t NANOS_PER_SEC = NANOS_PER_MSEC * MSECS_PER_SEC;
static constexpr const int64_t NANOS_PER_MINUTE = NANOS_PER_SEC * SECS_PER_MINUTE;
static constexpr const int64_t NANOS_PER_HOUR = NANOS_PER_MINUTE * MINS_PER_HOUR;
static constexpr const int64_t NANOS_PER_DAY = NANOS_PER_HOUR * HOURS_PER_DAY;
static constexpr const int64_t NANOS_PER_WEEK = NANOS_PER_DAY * DAYS_PER_WEEK;
public:
static bool FromString(const string &str, interval_t &result);
static bool FromCString(const char *str, idx_t len, interval_t &result, string *error_message, bool strict);
static string ToString(const interval_t &val);
DUCKDB_API static interval_t FromMicro(int64_t micros);
static int64_t GetMilli(const interval_t &val);
static int64_t GetMicro(const interval_t &val);
static int64_t GetNanoseconds(const interval_t &val);
static interval_t GetAge(timestamp_t timestamp_1, timestamp_t timestamp_2);
static interval_t GetDifference(timestamp_t timestamp_1, timestamp_t timestamp_2);
static interval_t Invert(interval_t interval);
static date_t Add(date_t left, interval_t right);
static timestamp_t Add(timestamp_t left, interval_t right);
static dtime_t Add(dtime_t left, interval_t right, date_t &date);
static bool Equals(interval_t left, interval_t right);
static bool GreaterThan(interval_t left, interval_t right);
static bool GreaterThanEquals(interval_t left, interval_t right);
};
}
namespace duckdb {
class CastFunctionSet;
class Deserializer;
class Serializer;
struct GetCastFunctionInput;
class Value {
friend struct StringValue;
friend struct StructValue;
friend struct ListValue;
friend struct UnionValue;
public:
DUCKDB_API explicit Value(LogicalType type = LogicalType::SQLNULL);
DUCKDB_API Value(int32_t val); DUCKDB_API Value(int64_t val); DUCKDB_API Value(float val); DUCKDB_API Value(double val); DUCKDB_API Value(const char *val); DUCKDB_API Value(std::nullptr_t val); DUCKDB_API Value(string_t val); DUCKDB_API Value(string val); DUCKDB_API Value(const Value &other);
DUCKDB_API Value(Value &&other) noexcept;
DUCKDB_API ~Value();
DUCKDB_API Value &operator=(const Value &other);
DUCKDB_API Value &operator=(Value &&other) noexcept;
inline LogicalType &GetTypeMutable() {
return type_;
}
inline const LogicalType &type() const {
return type_;
}
inline bool IsNull() const {
return is_null;
}
DUCKDB_API static Value MinimumValue(const LogicalType &type);
DUCKDB_API static Value MaximumValue(const LogicalType &type);
DUCKDB_API static Value Numeric(const LogicalType &type, int64_t value);
DUCKDB_API static Value Numeric(const LogicalType &type, hugeint_t value);
DUCKDB_API static Value BOOLEAN(int8_t value);
DUCKDB_API static Value TINYINT(int8_t value);
DUCKDB_API static Value SMALLINT(int16_t value);
DUCKDB_API static Value INTEGER(int32_t value);
DUCKDB_API static Value BIGINT(int64_t value);
DUCKDB_API static Value UTINYINT(uint8_t value);
DUCKDB_API static Value USMALLINT(uint16_t value);
DUCKDB_API static Value UINTEGER(uint32_t value);
DUCKDB_API static Value UBIGINT(uint64_t value);
DUCKDB_API static Value HUGEINT(hugeint_t value);
DUCKDB_API static Value UUID(const string &value);
DUCKDB_API static Value UUID(hugeint_t value);
DUCKDB_API static Value HASH(hash_t value);
DUCKDB_API static Value POINTER(uintptr_t value);
DUCKDB_API static Value DATE(date_t date);
DUCKDB_API static Value DATE(int32_t year, int32_t month, int32_t day);
DUCKDB_API static Value TIME(dtime_t time);
DUCKDB_API static Value TIMETZ(dtime_t time);
DUCKDB_API static Value TIME(int32_t hour, int32_t min, int32_t sec, int32_t micros);
DUCKDB_API static Value TIMESTAMP(date_t date, dtime_t time);
DUCKDB_API static Value TIMESTAMP(timestamp_t timestamp);
DUCKDB_API static Value TIMESTAMPNS(timestamp_t timestamp);
DUCKDB_API static Value TIMESTAMPMS(timestamp_t timestamp);
DUCKDB_API static Value TIMESTAMPSEC(timestamp_t timestamp);
DUCKDB_API static Value TIMESTAMPTZ(timestamp_t timestamp);
DUCKDB_API static Value TIMESTAMP(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec,
int32_t micros);
DUCKDB_API static Value INTERVAL(int32_t months, int32_t days, int64_t micros);
DUCKDB_API static Value INTERVAL(interval_t interval);
DUCKDB_API static Value ENUM(uint64_t value, const LogicalType &original_type);
DUCKDB_API static Value DECIMAL(int16_t value, uint8_t width, uint8_t scale);
DUCKDB_API static Value DECIMAL(int32_t value, uint8_t width, uint8_t scale);
DUCKDB_API static Value DECIMAL(int64_t value, uint8_t width, uint8_t scale);
DUCKDB_API static Value DECIMAL(hugeint_t value, uint8_t width, uint8_t scale);
DUCKDB_API static Value FLOAT(float value);
DUCKDB_API static Value DOUBLE(double value);
DUCKDB_API static Value STRUCT(child_list_t<Value> values);
DUCKDB_API static Value LIST(vector<Value> values);
DUCKDB_API static Value LIST(LogicalType child_type, vector<Value> values);
DUCKDB_API static Value EMPTYLIST(LogicalType child_type);
DUCKDB_API static Value MAP(LogicalType child_type, vector<Value> values);
DUCKDB_API static Value UNION(child_list_t<LogicalType> members, uint8_t tag, Value value);
DUCKDB_API static Value BLOB(const_data_ptr_t data, idx_t len);
DUCKDB_API static Value BLOB_RAW(const string &data) {
return Value::BLOB((const_data_ptr_t)data.c_str(), data.size());
}
DUCKDB_API static Value BLOB(const string &data);
DUCKDB_API static Value BIT(const_data_ptr_t data, idx_t len);
DUCKDB_API static Value BIT(const string &data);
template <class T>
T GetValue() const {
throw InternalException("Unimplemented template type for Value::GetValue");
}
template <class T>
static Value CreateValue(T value) {
throw InternalException("Unimplemented template type for Value::CreateValue");
}
template <class T>
T GetValueUnsafe() const {
throw InternalException("Unimplemented template type for Value::GetValueUnsafe");
}
template <class T>
T &GetReferenceUnsafe() {
throw InternalException("Unimplemented template type for Value::GetReferenceUnsafe");
}
Value Copy() const {
return Value(*this);
}
DUCKDB_API hash_t Hash() const;
DUCKDB_API string ToString() const;
DUCKDB_API string ToSQLString() const;
DUCKDB_API uintptr_t GetPointer() const;
DUCKDB_API Value CastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
bool strict = false) const;
DUCKDB_API Value CastAs(ClientContext &context, const LogicalType &target_type, bool strict = false) const;
DUCKDB_API Value DefaultCastAs(const LogicalType &target_type, bool strict = false) const;
DUCKDB_API bool TryCastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
Value &new_value, string *error_message, bool strict = false) const;
DUCKDB_API bool TryCastAs(ClientContext &context, const LogicalType &target_type, Value &new_value,
string *error_message, bool strict = false) const;
DUCKDB_API bool DefaultTryCastAs(const LogicalType &target_type, Value &new_value, string *error_message,
bool strict = false) const;
DUCKDB_API bool TryCastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
bool strict = false);
DUCKDB_API bool TryCastAs(ClientContext &context, const LogicalType &target_type, bool strict = false);
DUCKDB_API bool DefaultTryCastAs(const LogicalType &target_type, bool strict = false);
DUCKDB_API void Reinterpret(LogicalType new_type);
DUCKDB_API void Serialize(Serializer &serializer) const;
DUCKDB_API static Value Deserialize(Deserializer &source);
DUCKDB_API bool operator==(const Value &rhs) const;
DUCKDB_API bool operator!=(const Value &rhs) const;
DUCKDB_API bool operator<(const Value &rhs) const;
DUCKDB_API bool operator>(const Value &rhs) const;
DUCKDB_API bool operator<=(const Value &rhs) const;
DUCKDB_API bool operator>=(const Value &rhs) const;
DUCKDB_API bool operator==(const int64_t &rhs) const;
DUCKDB_API bool operator!=(const int64_t &rhs) const;
DUCKDB_API bool operator<(const int64_t &rhs) const;
DUCKDB_API bool operator>(const int64_t &rhs) const;
DUCKDB_API bool operator<=(const int64_t &rhs) const;
DUCKDB_API bool operator>=(const int64_t &rhs) const;
DUCKDB_API static bool FloatIsFinite(float value);
DUCKDB_API static bool DoubleIsFinite(double value);
template <class T>
static bool IsNan(T value) {
throw InternalException("Unimplemented template type for Value::IsNan");
}
template <class T>
static bool IsFinite(T value) {
return true;
}
DUCKDB_API static bool StringIsValid(const char *str, idx_t length);
static bool StringIsValid(const string &str) {
return StringIsValid(str.c_str(), str.size());
}
DUCKDB_API static bool ValuesAreEqual(CastFunctionSet &set, GetCastFunctionInput &get_input,
const Value &result_value, const Value &value);
DUCKDB_API static bool ValuesAreEqual(ClientContext &context, const Value &result_value, const Value &value);
DUCKDB_API static bool DefaultValuesAreEqual(const Value &result_value, const Value &value);
DUCKDB_API static bool NotDistinctFrom(const Value &lvalue, const Value &rvalue);
friend std::ostream &operator<<(std::ostream &out, const Value &val) {
out << val.ToString();
return out;
}
DUCKDB_API void Print() const;
private:
LogicalType type_;
#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2
public:
#endif
bool is_null;
union Val {
int8_t boolean;
int8_t tinyint;
int16_t smallint;
int32_t integer;
int64_t bigint;
uint8_t utinyint;
uint16_t usmallint;
uint32_t uinteger;
uint64_t ubigint;
hugeint_t hugeint;
float float_;
double double_;
uintptr_t pointer;
uint64_t hash;
date_t date;
dtime_t time;
timestamp_t timestamp;
interval_t interval;
} value_;
string str_value;
vector<Value> struct_value;
vector<Value> list_value;
private:
template <class T>
T GetValueInternal() const;
};
struct BooleanValue {
DUCKDB_API static bool Get(const Value &value);
};
struct TinyIntValue {
DUCKDB_API static int8_t Get(const Value &value);
};
struct SmallIntValue {
DUCKDB_API static int16_t Get(const Value &value);
};
struct IntegerValue {
DUCKDB_API static int32_t Get(const Value &value);
};
struct BigIntValue {
DUCKDB_API static int64_t Get(const Value &value);
};
struct HugeIntValue {
DUCKDB_API static hugeint_t Get(const Value &value);
};
struct UTinyIntValue {
DUCKDB_API static uint8_t Get(const Value &value);
};
struct USmallIntValue {
DUCKDB_API static uint16_t Get(const Value &value);
};
struct UIntegerValue {
DUCKDB_API static uint32_t Get(const Value &value);
};
struct UBigIntValue {
DUCKDB_API static uint64_t Get(const Value &value);
};
struct FloatValue {
DUCKDB_API static float Get(const Value &value);
};
struct DoubleValue {
DUCKDB_API static double Get(const Value &value);
};
struct StringValue {
DUCKDB_API static const string &Get(const Value &value);
};
struct DateValue {
DUCKDB_API static date_t Get(const Value &value);
};
struct TimeValue {
DUCKDB_API static dtime_t Get(const Value &value);
};
struct TimestampValue {
DUCKDB_API static timestamp_t Get(const Value &value);
};
struct IntervalValue {
DUCKDB_API static interval_t Get(const Value &value);
};
struct StructValue {
DUCKDB_API static const vector<Value> &GetChildren(const Value &value);
};
struct ListValue {
DUCKDB_API static const vector<Value> &GetChildren(const Value &value);
};
struct UnionValue {
DUCKDB_API static const Value &GetValue(const Value &value);
DUCKDB_API static uint8_t GetTag(const Value &value);
};
struct IntegralValue {
static hugeint_t Get(const Value &value);
};
template <>
Value DUCKDB_API Value::CreateValue(bool value);
template <>
Value DUCKDB_API Value::CreateValue(uint8_t value);
template <>
Value DUCKDB_API Value::CreateValue(uint16_t value);
template <>
Value DUCKDB_API Value::CreateValue(uint32_t value);
template <>
Value DUCKDB_API Value::CreateValue(uint64_t value);
template <>
Value DUCKDB_API Value::CreateValue(int8_t value);
template <>
Value DUCKDB_API Value::CreateValue(int16_t value);
template <>
Value DUCKDB_API Value::CreateValue(int32_t value);
template <>
Value DUCKDB_API Value::CreateValue(int64_t value);
template <>
Value DUCKDB_API Value::CreateValue(hugeint_t value);
template <>
Value DUCKDB_API Value::CreateValue(date_t value);
template <>
Value DUCKDB_API Value::CreateValue(dtime_t value);
template <>
Value DUCKDB_API Value::CreateValue(dtime_tz_t value);
template <>
Value DUCKDB_API Value::CreateValue(timestamp_t value);
template <>
Value DUCKDB_API Value::CreateValue(timestamp_sec_t value);
template <>
Value DUCKDB_API Value::CreateValue(timestamp_ms_t value);
template <>
Value DUCKDB_API Value::CreateValue(timestamp_ns_t value);
template <>
Value DUCKDB_API Value::CreateValue(timestamp_tz_t value);
template <>
Value DUCKDB_API Value::CreateValue(const char *value);
template <>
Value DUCKDB_API Value::CreateValue(string value);
template <>
Value DUCKDB_API Value::CreateValue(string_t value);
template <>
Value DUCKDB_API Value::CreateValue(float value);
template <>
Value DUCKDB_API Value::CreateValue(double value);
template <>
Value DUCKDB_API Value::CreateValue(interval_t value);
template <>
Value DUCKDB_API Value::CreateValue(Value value);
template <>
DUCKDB_API bool Value::GetValue() const;
template <>
DUCKDB_API int8_t Value::GetValue() const;
template <>
DUCKDB_API int16_t Value::GetValue() const;
template <>
DUCKDB_API int32_t Value::GetValue() const;
template <>
DUCKDB_API int64_t Value::GetValue() const;
template <>
DUCKDB_API uint8_t Value::GetValue() const;
template <>
DUCKDB_API uint16_t Value::GetValue() const;
template <>
DUCKDB_API uint32_t Value::GetValue() const;
template <>
DUCKDB_API uint64_t Value::GetValue() const;
template <>
DUCKDB_API hugeint_t Value::GetValue() const;
template <>
DUCKDB_API string Value::GetValue() const;
template <>
DUCKDB_API float Value::GetValue() const;
template <>
DUCKDB_API double Value::GetValue() const;
template <>
DUCKDB_API date_t Value::GetValue() const;
template <>
DUCKDB_API dtime_t Value::GetValue() const;
template <>
DUCKDB_API timestamp_t Value::GetValue() const;
template <>
DUCKDB_API interval_t Value::GetValue() const;
template <>
DUCKDB_API Value Value::GetValue() const;
template <>
DUCKDB_API bool Value::GetValueUnsafe() const;
template <>
DUCKDB_API int8_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API int16_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API int32_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API int64_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API hugeint_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API uint8_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API uint16_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API uint32_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API uint64_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API string Value::GetValueUnsafe() const;
template <>
DUCKDB_API string_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API float Value::GetValueUnsafe() const;
template <>
DUCKDB_API double Value::GetValueUnsafe() const;
template <>
DUCKDB_API date_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API dtime_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API timestamp_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API interval_t Value::GetValueUnsafe() const;
template <>
DUCKDB_API int8_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API int16_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API int32_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API int64_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API hugeint_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API uint8_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API uint16_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API uint32_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API uint64_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API float &Value::GetReferenceUnsafe();
template <>
DUCKDB_API double &Value::GetReferenceUnsafe();
template <>
DUCKDB_API date_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API dtime_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API timestamp_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API interval_t &Value::GetReferenceUnsafe();
template <>
DUCKDB_API bool Value::IsNan(float input);
template <>
DUCKDB_API bool Value::IsNan(double input);
template <>
DUCKDB_API bool Value::IsFinite(float input);
template <>
DUCKDB_API bool Value::IsFinite(double input);
template <>
DUCKDB_API bool Value::IsFinite(date_t input);
template <>
DUCKDB_API bool Value::IsFinite(timestamp_t input);
}
namespace duckdb {
class Allocator;
class AttachedDatabase;
class ClientContext;
class DatabaseInstance;
class ExecutionContext;
class ThreadContext;
struct AllocatorDebugInfo;
struct PrivateAllocatorData {
PrivateAllocatorData();
virtual ~PrivateAllocatorData();
unique_ptr<AllocatorDebugInfo> debug_info;
};
typedef data_ptr_t (*allocate_function_ptr_t)(PrivateAllocatorData *private_data, idx_t size);
typedef void (*free_function_ptr_t)(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size);
typedef data_ptr_t (*reallocate_function_ptr_t)(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t old_size,
idx_t size);
class AllocatedData {
public:
DUCKDB_API AllocatedData();
DUCKDB_API AllocatedData(Allocator &allocator, data_ptr_t pointer, idx_t allocated_size);
DUCKDB_API ~AllocatedData();
AllocatedData(const AllocatedData &other) = delete;
AllocatedData &operator=(const AllocatedData &) = delete;
DUCKDB_API AllocatedData(AllocatedData &&other) noexcept;
DUCKDB_API AllocatedData &operator=(AllocatedData &&) noexcept;
data_ptr_t get() {
return pointer;
}
const_data_ptr_t get() const {
return pointer;
}
idx_t GetSize() const {
return allocated_size;
}
void Reset();
private:
Allocator *allocator;
data_ptr_t pointer;
idx_t allocated_size;
};
class Allocator {
static constexpr const idx_t MAXIMUM_ALLOC_SIZE = 281474976710656ULL;
public:
DUCKDB_API Allocator();
DUCKDB_API Allocator(allocate_function_ptr_t allocate_function_p, free_function_ptr_t free_function_p,
reallocate_function_ptr_t reallocate_function_p,
unique_ptr<PrivateAllocatorData> private_data);
Allocator &operator=(Allocator &&allocator) noexcept = delete;
DUCKDB_API ~Allocator();
DUCKDB_API data_ptr_t AllocateData(idx_t size);
DUCKDB_API void FreeData(data_ptr_t pointer, idx_t size);
DUCKDB_API data_ptr_t ReallocateData(data_ptr_t pointer, idx_t old_size, idx_t new_size);
AllocatedData Allocate(idx_t size) {
return AllocatedData(*this, AllocateData(size), size);
}
static data_ptr_t DefaultAllocate(PrivateAllocatorData *private_data, idx_t size) {
return (data_ptr_t)malloc(size);
}
static void DefaultFree(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size) {
free(pointer);
}
static data_ptr_t DefaultReallocate(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t old_size,
idx_t size) {
return (data_ptr_t)realloc(pointer, size);
}
static Allocator &Get(ClientContext &context);
static Allocator &Get(DatabaseInstance &db);
static Allocator &Get(AttachedDatabase &db);
PrivateAllocatorData *GetPrivateData() {
return private_data.get();
}
DUCKDB_API static Allocator &DefaultAllocator();
DUCKDB_API static shared_ptr<Allocator> &DefaultAllocatorReference();
private:
allocate_function_ptr_t allocate_function;
free_function_ptr_t free_function;
reallocate_function_ptr_t reallocate_function;
unique_ptr<PrivateAllocatorData> private_data;
};
template <class T>
T *AllocateArray(idx_t size) {
return (T *)Allocator::DefaultAllocator().AllocateData(size * sizeof(T));
}
template <class T>
void DeleteArray(T *ptr, idx_t size) {
Allocator::DefaultAllocator().FreeData((data_ptr_t)ptr, size * sizeof(T));
}
template <typename T, typename... ARGS>
T *AllocateObject(ARGS &&... args) {
auto data = Allocator::DefaultAllocator().AllocateData(sizeof(T));
return new (data) T(std::forward<ARGS>(args)...);
}
template <typename T>
void DestroyObject(T *ptr) {
ptr->~T();
Allocator::DefaultAllocator().FreeData((data_ptr_t)ptr, sizeof(T));
}
struct BufferAllocator {
DUCKDB_API static Allocator &Get(ClientContext &context);
DUCKDB_API static Allocator &Get(DatabaseInstance &db);
DUCKDB_API static Allocator &Get(AttachedDatabase &db);
};
}
namespace duckdb {
struct ArenaChunk {
ArenaChunk(Allocator &allocator, idx_t size);
~ArenaChunk();
AllocatedData data;
idx_t current_position;
idx_t maximum_size;
unique_ptr<ArenaChunk> next;
ArenaChunk *prev;
};
class ArenaAllocator {
static constexpr const idx_t ARENA_ALLOCATOR_INITIAL_CAPACITY = 2048;
public:
DUCKDB_API ArenaAllocator(Allocator &allocator, idx_t initial_capacity = ARENA_ALLOCATOR_INITIAL_CAPACITY);
DUCKDB_API ~ArenaAllocator();
DUCKDB_API data_ptr_t Allocate(idx_t size);
DUCKDB_API data_ptr_t Reallocate(data_ptr_t pointer, idx_t old_size, idx_t size);
DUCKDB_API data_ptr_t AllocateAligned(idx_t size);
DUCKDB_API data_ptr_t ReallocateAligned(data_ptr_t pointer, idx_t old_size, idx_t size);
DUCKDB_API void Reset();
DUCKDB_API void Destroy();
DUCKDB_API void Move(ArenaAllocator &allocator);
DUCKDB_API ArenaChunk *GetHead();
DUCKDB_API ArenaChunk *GetTail();
DUCKDB_API bool IsEmpty();
private:
Allocator &allocator;
idx_t current_capacity;
unique_ptr<ArenaChunk> head;
ArenaChunk *tail;
};
}
namespace duckdb {
class StringHeap {
public:
DUCKDB_API StringHeap(Allocator &allocator = Allocator::DefaultAllocator());
DUCKDB_API void Destroy();
DUCKDB_API void Move(StringHeap &other);
DUCKDB_API string_t AddString(const char *data, idx_t len);
DUCKDB_API string_t AddString(const char *data);
DUCKDB_API string_t AddString(const string &data);
DUCKDB_API string_t AddString(const string_t &data);
DUCKDB_API string_t AddBlob(const string_t &data);
DUCKDB_API string_t AddBlob(const char *data, idx_t len);
DUCKDB_API string_t EmptyString(idx_t len);
private:
ArenaAllocator allocator;
};
}
namespace duckdb {
class Serializer;
class Deserializer;
struct FileHandle;
#define STANDARD_ROW_GROUPS_SIZE 122880
#if STANDARD_ROW_GROUPS_SIZE < STANDARD_VECTOR_SIZE
#error Row groups should be able to hold at least one vector
#endif
#if ((STANDARD_ROW_GROUPS_SIZE % STANDARD_VECTOR_SIZE) != 0)
#error Row group size should be cleanly divisible by vector size
#endif
extern const uint64_t VERSION_NUMBER;
const char *GetDuckDBVersion(idx_t version_number);
using block_id_t = int64_t;
#define INVALID_BLOCK (-1)
#define MAXIMUM_BLOCK 4611686018427388000LL
struct MainHeader {
static constexpr idx_t MAGIC_BYTE_SIZE = 4;
static constexpr idx_t MAGIC_BYTE_OFFSET = Storage::BLOCK_HEADER_SIZE;
static constexpr idx_t FLAG_COUNT = 4;
static const char MAGIC_BYTES[];
uint64_t version_number;
uint64_t flags[FLAG_COUNT];
static void CheckMagicBytes(FileHandle &handle);
void Serialize(Serializer &ser);
static MainHeader Deserialize(Deserializer &source);
};
struct DatabaseHeader {
uint64_t iteration;
block_id_t meta_block;
block_id_t free_list;
uint64_t block_count;
void Serialize(Serializer &ser);
static DatabaseHeader Deserialize(Deserializer &source);
};
}
namespace duckdb {
class BlockHandle;
class FileBuffer;
class BufferHandle {
public:
DUCKDB_API BufferHandle();
DUCKDB_API BufferHandle(shared_ptr<BlockHandle> handle, FileBuffer *node);
DUCKDB_API ~BufferHandle();
BufferHandle(const BufferHandle &other) = delete;
BufferHandle &operator=(const BufferHandle &) = delete;
DUCKDB_API BufferHandle(BufferHandle &&other) noexcept;
DUCKDB_API BufferHandle &operator=(BufferHandle &&) noexcept;
public:
DUCKDB_API bool IsValid() const;
DUCKDB_API data_ptr_t Ptr() const;
DUCKDB_API data_ptr_t Ptr();
DUCKDB_API FileBuffer &GetFileBuffer();
DUCKDB_API void Destroy();
const shared_ptr<BlockHandle> &GetBlockHandle() const {
return handle;
}
private:
shared_ptr<BlockHandle> handle;
FileBuffer *node;
};
}
namespace duckdb {
class BufferHandle;
class VectorBuffer;
class Vector;
enum class VectorBufferType : uint8_t {
STANDARD_BUFFER, DICTIONARY_BUFFER, VECTOR_CHILD_BUFFER, STRING_BUFFER, FSST_BUFFER, STRUCT_BUFFER, LIST_BUFFER, MANAGED_BUFFER, OPAQUE_BUFFER };
enum class VectorAuxiliaryDataType : uint8_t {
ARROW_AUXILIARY };
struct VectorAuxiliaryData {
explicit VectorAuxiliaryData(VectorAuxiliaryDataType type_p)
: type(type_p) {
};
VectorAuxiliaryDataType type;
virtual ~VectorAuxiliaryData() {
}
};
class VectorBuffer {
public:
explicit VectorBuffer(VectorBufferType type) : buffer_type(type) {
}
explicit VectorBuffer(idx_t data_size) : buffer_type(VectorBufferType::STANDARD_BUFFER) {
if (data_size > 0) {
data = unique_ptr<data_t[]>(new data_t[data_size]);
}
}
explicit VectorBuffer(unique_ptr<data_t[]> data_p)
: buffer_type(VectorBufferType::STANDARD_BUFFER), data(std::move(data_p)) {
}
virtual ~VectorBuffer() {
}
VectorBuffer() {
}
public:
data_ptr_t GetData() {
return data.get();
}
void SetData(unique_ptr<data_t[]> new_data) {
data = std::move(new_data);
}
VectorAuxiliaryData *GetAuxiliaryData() {
return aux_data.get();
}
void SetAuxiliaryData(unique_ptr<VectorAuxiliaryData> aux_data_p) {
aux_data = std::move(aux_data_p);
}
static buffer_ptr<VectorBuffer> CreateStandardVector(PhysicalType type, idx_t capacity = STANDARD_VECTOR_SIZE);
static buffer_ptr<VectorBuffer> CreateConstantVector(PhysicalType type);
static buffer_ptr<VectorBuffer> CreateConstantVector(const LogicalType &logical_type);
static buffer_ptr<VectorBuffer> CreateStandardVector(const LogicalType &logical_type,
idx_t capacity = STANDARD_VECTOR_SIZE);
inline VectorBufferType GetBufferType() const {
return buffer_type;
}
inline VectorAuxiliaryDataType GetAuxiliaryDataType() const {
return aux_data->type;
}
protected:
VectorBufferType buffer_type;
unique_ptr<VectorAuxiliaryData> aux_data;
unique_ptr<data_t[]> data;
};
class DictionaryBuffer : public VectorBuffer {
public:
explicit DictionaryBuffer(const SelectionVector &sel)
: VectorBuffer(VectorBufferType::DICTIONARY_BUFFER), sel_vector(sel) {
}
explicit DictionaryBuffer(buffer_ptr<SelectionData> data)
: VectorBuffer(VectorBufferType::DICTIONARY_BUFFER), sel_vector(std::move(data)) {
}
explicit DictionaryBuffer(idx_t count = STANDARD_VECTOR_SIZE)
: VectorBuffer(VectorBufferType::DICTIONARY_BUFFER), sel_vector(count) {
}
public:
const SelectionVector &GetSelVector() const {
return sel_vector;
}
SelectionVector &GetSelVector() {
return sel_vector;
}
void SetSelVector(const SelectionVector &vector) {
this->sel_vector.Initialize(vector);
}
private:
SelectionVector sel_vector;
};
class VectorStringBuffer : public VectorBuffer {
public:
VectorStringBuffer();
VectorStringBuffer(VectorBufferType type);
public:
string_t AddString(const char *data, idx_t len) {
return heap.AddString(data, len);
}
string_t AddString(string_t data) {
return heap.AddString(data);
}
string_t AddBlob(string_t data) {
return heap.AddBlob(data.GetDataUnsafe(), data.GetSize());
}
string_t EmptyString(idx_t len) {
return heap.EmptyString(len);
}
void AddHeapReference(buffer_ptr<VectorBuffer> heap) {
references.push_back(std::move(heap));
}
private:
StringHeap heap;
vector<buffer_ptr<VectorBuffer>> references;
};
class VectorFSSTStringBuffer : public VectorStringBuffer {
public:
VectorFSSTStringBuffer();
public:
void AddDecoder(buffer_ptr<void> &duckdb_fsst_decoder_p) {
duckdb_fsst_decoder = duckdb_fsst_decoder_p;
}
void *GetDecoder() {
return duckdb_fsst_decoder.get();
}
void SetCount(idx_t count) {
total_string_count = count;
}
idx_t GetCount() {
return total_string_count;
}
private:
buffer_ptr<void> duckdb_fsst_decoder;
idx_t total_string_count = 0;
};
class VectorStructBuffer : public VectorBuffer {
public:
VectorStructBuffer();
VectorStructBuffer(const LogicalType &struct_type, idx_t capacity = STANDARD_VECTOR_SIZE);
VectorStructBuffer(Vector &other, const SelectionVector &sel, idx_t count);
~VectorStructBuffer() override;
public:
const vector<unique_ptr<Vector>> &GetChildren() const {
return children;
}
vector<unique_ptr<Vector>> &GetChildren() {
return children;
}
private:
vector<unique_ptr<Vector>> children;
};
class VectorListBuffer : public VectorBuffer {
public:
VectorListBuffer(unique_ptr<Vector> vector, idx_t initial_capacity = STANDARD_VECTOR_SIZE);
VectorListBuffer(const LogicalType &list_type, idx_t initial_capacity = STANDARD_VECTOR_SIZE);
~VectorListBuffer() override;
public:
Vector &GetChild() {
return *child;
}
void Reserve(idx_t to_reserve);
void Append(const Vector &to_append, idx_t to_append_size, idx_t source_offset = 0);
void Append(const Vector &to_append, const SelectionVector &sel, idx_t to_append_size, idx_t source_offset = 0);
void PushBack(const Value &insert);
idx_t capacity = 0;
idx_t size = 0;
private:
unique_ptr<Vector> child;
};
class ManagedVectorBuffer : public VectorBuffer {
public:
explicit ManagedVectorBuffer(BufferHandle handle);
~ManagedVectorBuffer() override;
private:
BufferHandle handle;
};
}
namespace duckdb {
struct UnifiedVectorFormat {
const SelectionVector *sel;
data_ptr_t data;
ValidityMask validity;
SelectionVector owned_sel;
};
class VectorCache;
class VectorStructBuffer;
class VectorListBuffer;
struct SelCache;
struct ConsecutiveChildListInfo {
ConsecutiveChildListInfo() : is_constant(true), needs_slicing(false), child_list_info(list_entry_t(0, 0)) {
}
bool is_constant;
bool needs_slicing;
list_entry_t child_list_info;
};
class Vector {
friend struct ConstantVector;
friend struct DictionaryVector;
friend struct FlatVector;
friend struct ListVector;
friend struct StringVector;
friend struct FSSTVector;
friend struct StructVector;
friend struct UnionVector;
friend struct SequenceVector;
friend class DataChunk;
friend class VectorCacheBuffer;
public:
DUCKDB_API Vector(Vector &other);
DUCKDB_API explicit Vector(Vector &other, const SelectionVector &sel, idx_t count);
DUCKDB_API explicit Vector(Vector &other, idx_t offset, idx_t end);
DUCKDB_API explicit Vector(const Value &value);
DUCKDB_API explicit Vector(LogicalType type, idx_t capacity = STANDARD_VECTOR_SIZE);
DUCKDB_API explicit Vector(const VectorCache &cache);
DUCKDB_API Vector(LogicalType type, data_ptr_t dataptr);
DUCKDB_API Vector(LogicalType type, bool create_data, bool zero_data, idx_t capacity = STANDARD_VECTOR_SIZE);
Vector(const Vector &) = delete;
DUCKDB_API Vector(Vector &&other) noexcept;
public:
DUCKDB_API void Reference(const Value &value);
DUCKDB_API void Reference(Vector &other);
DUCKDB_API void Reinterpret(Vector &other);
DUCKDB_API void ReferenceAndSetType(Vector &other);
DUCKDB_API void ResetFromCache(const VectorCache &cache);
DUCKDB_API void Slice(Vector &other, idx_t offset, idx_t end);
DUCKDB_API void Slice(Vector &other, const SelectionVector &sel, idx_t count);
DUCKDB_API void Slice(const SelectionVector &sel, idx_t count);
DUCKDB_API void Slice(const SelectionVector &sel, idx_t count, SelCache &cache);
DUCKDB_API void Initialize(bool zero_data = false, idx_t capacity = STANDARD_VECTOR_SIZE);
DUCKDB_API string ToString(idx_t count) const;
DUCKDB_API void Print(idx_t count) const;
DUCKDB_API string ToString() const;
DUCKDB_API void Print() const;
DUCKDB_API void Flatten(idx_t count);
DUCKDB_API void Flatten(const SelectionVector &sel, idx_t count);
DUCKDB_API void ToUnifiedFormat(idx_t count, UnifiedVectorFormat &data);
DUCKDB_API void Sequence(int64_t start, int64_t increment, idx_t count);
DUCKDB_API void Verify(idx_t count);
DUCKDB_API static void VerifyMap(Vector &map, const SelectionVector &sel, idx_t count);
DUCKDB_API static void VerifyUnion(Vector &map, const SelectionVector &sel, idx_t count);
DUCKDB_API static void Verify(Vector &vector, const SelectionVector &sel, idx_t count);
DUCKDB_API void UTFVerify(idx_t count);
DUCKDB_API void UTFVerify(const SelectionVector &sel, idx_t count);
DUCKDB_API Value GetValue(idx_t index) const;
DUCKDB_API void SetValue(idx_t index, const Value &val);
inline void SetAuxiliary(buffer_ptr<VectorBuffer> new_buffer) {
auxiliary = std::move(new_buffer);
};
DUCKDB_API void Resize(idx_t cur_size, idx_t new_size);
DUCKDB_API void Serialize(idx_t count, Serializer &serializer);
DUCKDB_API void Deserialize(idx_t count, Deserializer &source);
inline VectorType GetVectorType() const {
return vector_type;
}
inline const LogicalType &GetType() const {
return type;
}
inline data_ptr_t GetData() {
return data;
}
inline buffer_ptr<VectorBuffer> GetAuxiliary() {
return auxiliary;
}
inline buffer_ptr<VectorBuffer> GetBuffer() {
return buffer;
}
DUCKDB_API void SetVectorType(VectorType vector_type);
private:
static Value GetValue(const Vector &v, idx_t index);
static Value GetValueInternal(const Vector &v, idx_t index);
protected:
VectorType vector_type;
LogicalType type;
data_ptr_t data;
ValidityMask validity;
buffer_ptr<VectorBuffer> buffer;
buffer_ptr<VectorBuffer> auxiliary;
};
class VectorChildBuffer : public VectorBuffer {
public:
explicit VectorChildBuffer(Vector vector)
: VectorBuffer(VectorBufferType::VECTOR_CHILD_BUFFER), data(std::move(vector)) {
}
public:
Vector data;
};
struct ConstantVector {
static inline const_data_ptr_t GetData(const Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::CONSTANT_VECTOR ||
vector.GetVectorType() == VectorType::FLAT_VECTOR);
return vector.data;
}
static inline data_ptr_t GetData(Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::CONSTANT_VECTOR ||
vector.GetVectorType() == VectorType::FLAT_VECTOR);
return vector.data;
}
template <class T>
static inline const T *GetData(const Vector &vector) {
return (const T *)ConstantVector::GetData(vector);
}
template <class T>
static inline T *GetData(Vector &vector) {
return (T *)ConstantVector::GetData(vector);
}
static inline bool IsNull(const Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::CONSTANT_VECTOR);
return !vector.validity.RowIsValid(0);
}
DUCKDB_API static void SetNull(Vector &vector, bool is_null);
static inline ValidityMask &Validity(Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::CONSTANT_VECTOR);
return vector.validity;
}
DUCKDB_API static const SelectionVector *ZeroSelectionVector(idx_t count, SelectionVector &owned_sel);
DUCKDB_API static const SelectionVector *ZeroSelectionVector();
DUCKDB_API static void Reference(Vector &vector, Vector &source, idx_t position, idx_t count);
static const sel_t ZERO_VECTOR[STANDARD_VECTOR_SIZE];
};
struct DictionaryVector {
static inline const SelectionVector &SelVector(const Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::DICTIONARY_VECTOR);
return ((const DictionaryBuffer &)*vector.buffer).GetSelVector();
}
static inline SelectionVector &SelVector(Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::DICTIONARY_VECTOR);
return ((DictionaryBuffer &)*vector.buffer).GetSelVector();
}
static inline const Vector &Child(const Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::DICTIONARY_VECTOR);
return ((const VectorChildBuffer &)*vector.auxiliary).data;
}
static inline Vector &Child(Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::DICTIONARY_VECTOR);
return ((VectorChildBuffer &)*vector.auxiliary).data;
}
};
struct FlatVector {
static inline data_ptr_t GetData(Vector &vector) {
return ConstantVector::GetData(vector);
}
template <class T>
static inline const T *GetData(const Vector &vector) {
return ConstantVector::GetData<T>(vector);
}
template <class T>
static inline T *GetData(Vector &vector) {
return ConstantVector::GetData<T>(vector);
}
static inline void SetData(Vector &vector, data_ptr_t data) {
D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR);
vector.data = data;
}
template <class T>
static inline T GetValue(Vector &vector, idx_t idx) {
D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR);
return FlatVector::GetData<T>(vector)[idx];
}
static inline const ValidityMask &Validity(const Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR);
return vector.validity;
}
static inline ValidityMask &Validity(Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR);
return vector.validity;
}
static inline void SetValidity(Vector &vector, ValidityMask &new_validity) {
D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR);
vector.validity.Initialize(new_validity);
}
DUCKDB_API static void SetNull(Vector &vector, idx_t idx, bool is_null);
static inline bool IsNull(const Vector &vector, idx_t idx) {
D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR);
return !vector.validity.RowIsValid(idx);
}
DUCKDB_API static const SelectionVector *IncrementalSelectionVector();
static Value GetValuesFromOffsets(Vector &values, vector<idx_t> &offsets);
};
struct ListVector {
static inline list_entry_t *GetData(Vector &v) {
if (v.GetVectorType() == VectorType::DICTIONARY_VECTOR) {
auto &child = DictionaryVector::Child(v);
return GetData(child);
}
return FlatVector::GetData<list_entry_t>(v);
}
DUCKDB_API static const Vector &GetEntry(const Vector &vector);
DUCKDB_API static Vector &GetEntry(Vector &vector);
DUCKDB_API static idx_t GetListSize(const Vector &vector);
DUCKDB_API static void SetListSize(Vector &vec, idx_t size);
DUCKDB_API static idx_t GetListCapacity(const Vector &vector);
DUCKDB_API static void Reserve(Vector &vec, idx_t required_capacity);
DUCKDB_API static void Append(Vector &target, const Vector &source, idx_t source_size, idx_t source_offset = 0);
DUCKDB_API static void Append(Vector &target, const Vector &source, const SelectionVector &sel, idx_t source_size,
idx_t source_offset = 0);
DUCKDB_API static void PushBack(Vector &target, const Value &insert);
DUCKDB_API static idx_t GetConsecutiveChildList(Vector &list, Vector &result, idx_t offset, idx_t count);
DUCKDB_API static ConsecutiveChildListInfo GetConsecutiveChildListInfo(Vector &list, idx_t offset, idx_t count);
DUCKDB_API static void GetConsecutiveChildSelVector(Vector &list, SelectionVector &sel, idx_t offset, idx_t count);
DUCKDB_API static void ReferenceEntry(Vector &vector, Vector &other);
};
struct StringVector {
DUCKDB_API static string_t AddString(Vector &vector, const char *data, idx_t len);
DUCKDB_API static string_t AddStringOrBlob(Vector &vector, const char *data, idx_t len);
DUCKDB_API static string_t AddString(Vector &vector, const char *data);
DUCKDB_API static string_t AddString(Vector &vector, string_t data);
DUCKDB_API static string_t AddString(Vector &vector, const string &data);
DUCKDB_API static string_t AddStringOrBlob(Vector &vector, string_t data);
DUCKDB_API static string_t EmptyString(Vector &vector, idx_t len);
DUCKDB_API static void AddHandle(Vector &vector, BufferHandle handle);
DUCKDB_API static void AddBuffer(Vector &vector, buffer_ptr<VectorBuffer> buffer);
DUCKDB_API static void AddHeapReference(Vector &vector, Vector &other);
};
struct FSSTVector {
static inline const ValidityMask &Validity(const Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::FSST_VECTOR);
return vector.validity;
}
static inline ValidityMask &Validity(Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::FSST_VECTOR);
return vector.validity;
}
static inline void SetValidity(Vector &vector, ValidityMask &new_validity) {
D_ASSERT(vector.GetVectorType() == VectorType::FSST_VECTOR);
vector.validity.Initialize(new_validity);
}
static inline const_data_ptr_t GetCompressedData(const Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::FSST_VECTOR);
return vector.data;
}
static inline data_ptr_t GetCompressedData(Vector &vector) {
D_ASSERT(vector.GetVectorType() == VectorType::FSST_VECTOR);
return vector.data;
}
template <class T>
static inline const T *GetCompressedData(const Vector &vector) {
return (const T *)FSSTVector::GetCompressedData(vector);
}
template <class T>
static inline T *GetCompressedData(Vector &vector) {
return (T *)FSSTVector::GetCompressedData(vector);
}
static void DecompressVector(const Vector &src, Vector &dst, idx_t src_offset, idx_t dst_offset, idx_t copy_count,
const SelectionVector *sel);
DUCKDB_API static string_t AddCompressedString(Vector &vector, string_t data);
DUCKDB_API static string_t AddCompressedString(Vector &vector, const char *data, idx_t len);
DUCKDB_API static void RegisterDecoder(Vector &vector, buffer_ptr<void> &duckdb_fsst_decoder);
DUCKDB_API static void *GetDecoder(const Vector &vector);
DUCKDB_API static void SetCount(Vector &vector, idx_t count);
DUCKDB_API static idx_t GetCount(Vector &vector);
};
struct MapVector {
DUCKDB_API static const Vector &GetKeys(const Vector &vector);
DUCKDB_API static const Vector &GetValues(const Vector &vector);
DUCKDB_API static Vector &GetKeys(Vector &vector);
DUCKDB_API static Vector &GetValues(Vector &vector);
static vector<idx_t> Search(Vector &keys, idx_t count, const Value &key, list_entry_t &entry);
};
struct StructVector {
DUCKDB_API static const vector<unique_ptr<Vector>> &GetEntries(const Vector &vector);
DUCKDB_API static vector<unique_ptr<Vector>> &GetEntries(Vector &vector);
};
struct UnionVector {
DUCKDB_API static const Vector &GetTags(const Vector &v);
DUCKDB_API static Vector &GetTags(Vector &v);
DUCKDB_API static union_tag_t GetTag(const Vector &vector, idx_t index);
DUCKDB_API static const Vector &GetMember(const Vector &vector, idx_t member_index);
DUCKDB_API static Vector &GetMember(Vector &vector, idx_t member_index);
DUCKDB_API static void SetToMember(Vector &vector, union_tag_t tag, Vector &member_vector, idx_t count,
bool keep_tags_for_null);
};
struct SequenceVector {
static void GetSequence(const Vector &vector, int64_t &start, int64_t &increment, int64_t &sequence_count) {
D_ASSERT(vector.GetVectorType() == VectorType::SEQUENCE_VECTOR);
auto data = (int64_t *)vector.buffer->GetData();
start = data[0];
increment = data[1];
sequence_count = data[2];
}
static void GetSequence(const Vector &vector, int64_t &start, int64_t &increment) {
int64_t sequence_count;
GetSequence(vector, start, increment, sequence_count);
}
};
}
#ifndef ARROW_FLAG_DICTIONARY_ORDERED
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ARROW_C_DATA_INTERFACE
#define ARROW_C_DATA_INTERFACE
#define ARROW_FLAG_DICTIONARY_ORDERED 1
#define ARROW_FLAG_NULLABLE 2
#define ARROW_FLAG_MAP_KEYS_SORTED 4
struct ArrowSchema {
const char *format;
const char *name;
const char *metadata;
int64_t flags;
int64_t n_children;
struct ArrowSchema **children;
struct ArrowSchema *dictionary;
void (*release)(struct ArrowSchema *);
void *private_data;
};
struct ArrowArray {
int64_t length;
int64_t null_count;
int64_t offset;
int64_t n_buffers;
int64_t n_children;
const void **buffers;
struct ArrowArray **children;
struct ArrowArray *dictionary;
void (*release)(struct ArrowArray *);
void *private_data;
};
#endif
#ifndef ARROW_C_STREAM_INTERFACE
#define ARROW_C_STREAM_INTERFACE
struct ArrowArrayStream {
int (*get_schema)(struct ArrowArrayStream *, struct ArrowSchema *out);
int (*get_next)(struct ArrowArrayStream *, struct ArrowArray *out);
const char *(*get_last_error)(struct ArrowArrayStream *);
void (*release)(struct ArrowArrayStream *);
void *private_data;
};
#endif
#ifdef __cplusplus
}
#endif
#endif
namespace duckdb {
class PreservedError {
public:
DUCKDB_API PreservedError();
PreservedError(const std::exception &ex)
: initialized(true), type(ExceptionType::INVALID), raw_message(SanitizeErrorMessage(ex.what())) {
}
DUCKDB_API explicit PreservedError(const string &raw_message);
DUCKDB_API PreservedError(const Exception &exception);
public:
[[noreturn]] DUCKDB_API void Throw(const string &prepended_message = "") const;
DUCKDB_API const ExceptionType &Type() const;
DUCKDB_API PreservedError &AddToMessage(const string &prepended_message);
DUCKDB_API const string &Message();
DUCKDB_API operator bool() const;
DUCKDB_API bool operator==(const PreservedError &other) const;
private:
bool initialized;
ExceptionType type;
string raw_message;
string final_message;
private:
DUCKDB_API static string SanitizeErrorMessage(string error);
};
}
namespace duckdb {
class QueryResult;
class DataChunk;
class ArrowSchemaWrapper {
public:
ArrowSchema arrow_schema;
ArrowSchemaWrapper() {
arrow_schema.release = nullptr;
}
~ArrowSchemaWrapper();
};
class ArrowArrayWrapper {
public:
ArrowArray arrow_array;
ArrowArrayWrapper() {
arrow_array.length = 0;
arrow_array.release = nullptr;
}
~ArrowArrayWrapper();
};
class ArrowArrayStreamWrapper {
public:
ArrowArrayStream arrow_array_stream;
int64_t number_of_rows;
public:
void GetSchema(ArrowSchemaWrapper &schema);
shared_ptr<ArrowArrayWrapper> GetNextChunk();
const char *GetError();
~ArrowArrayStreamWrapper();
ArrowArrayStreamWrapper() {
arrow_array_stream.release = nullptr;
}
};
class ArrowUtil {
public:
static bool TryFetchChunk(QueryResult *result, idx_t chunk_size, ArrowArray *out, idx_t &result_count,
PreservedError &error);
static idx_t FetchChunk(QueryResult *result, idx_t chunk_size, ArrowArray *out);
private:
static bool TryFetchNext(QueryResult &result, unique_ptr<DataChunk> &out, PreservedError &error);
};
}
struct ArrowArray;
namespace duckdb {
class Allocator;
class ClientContext;
class ExecutionContext;
class VectorCache;
class DataChunk {
public:
DUCKDB_API DataChunk();
DUCKDB_API ~DataChunk();
vector<Vector> data;
public:
inline idx_t size() const { return count;
}
inline idx_t ColumnCount() const {
return data.size();
}
inline void SetCardinality(idx_t count_p) {
D_ASSERT(count_p <= capacity);
this->count = count_p;
}
inline void SetCardinality(const DataChunk &other) {
SetCardinality(other.size());
}
inline void SetCapacity(idx_t capacity_p) {
this->capacity = capacity_p;
}
inline void SetCapacity(const DataChunk &other) {
SetCapacity(other.capacity);
}
DUCKDB_API Value GetValue(idx_t col_idx, idx_t index) const;
DUCKDB_API void SetValue(idx_t col_idx, idx_t index, const Value &val);
DUCKDB_API bool AllConstant() const;
DUCKDB_API void Reference(DataChunk &chunk);
DUCKDB_API void Move(DataChunk &chunk);
DUCKDB_API void Initialize(Allocator &allocator, const vector<LogicalType> &types,
idx_t capacity = STANDARD_VECTOR_SIZE);
DUCKDB_API void Initialize(ClientContext &context, const vector<LogicalType> &types,
idx_t capacity = STANDARD_VECTOR_SIZE);
DUCKDB_API void InitializeEmpty(const vector<LogicalType> &types);
DUCKDB_API void InitializeEmpty(vector<LogicalType>::const_iterator begin, vector<LogicalType>::const_iterator end);
DUCKDB_API void Initialize(Allocator &allocator, vector<LogicalType>::const_iterator begin,
vector<LogicalType>::const_iterator end, idx_t capacity = STANDARD_VECTOR_SIZE);
DUCKDB_API void Initialize(ClientContext &context, vector<LogicalType>::const_iterator begin,
vector<LogicalType>::const_iterator end, idx_t capacity = STANDARD_VECTOR_SIZE);
DUCKDB_API void Append(const DataChunk &other, bool resize = false, SelectionVector *sel = nullptr,
idx_t count = 0);
DUCKDB_API void Destroy();
DUCKDB_API void Copy(DataChunk &other, idx_t offset = 0) const;
DUCKDB_API void Copy(DataChunk &other, const SelectionVector &sel, const idx_t source_count,
const idx_t offset = 0) const;
DUCKDB_API void Split(DataChunk &other, idx_t split_idx);
DUCKDB_API void Fuse(DataChunk &other);
DUCKDB_API void ReferenceColumns(DataChunk &other, const vector<column_t> &column_ids);
DUCKDB_API void Flatten();
DUCKDB_API unique_ptr<UnifiedVectorFormat[]> ToUnifiedFormat();
DUCKDB_API void Slice(const SelectionVector &sel_vector, idx_t count);
DUCKDB_API void Slice(DataChunk &other, const SelectionVector &sel, idx_t count, idx_t col_offset = 0);
DUCKDB_API void Reset();
DUCKDB_API void Serialize(Serializer &serializer);
DUCKDB_API void Deserialize(Deserializer &source);
DUCKDB_API void Hash(Vector &result);
DUCKDB_API void Hash(vector<idx_t> &column_ids, Vector &result);
DUCKDB_API vector<LogicalType> GetTypes();
DUCKDB_API string ToString() const;
DUCKDB_API void Print();
DataChunk(const DataChunk &) = delete;
DUCKDB_API void Verify();
private:
idx_t count;
idx_t capacity;
vector<VectorCache> vector_caches;
};
}
#include <functional>
namespace duckdb {
class CastFunctionSet;
struct GetCastFunctionInput;
struct VectorOperations {
static void AddInPlace(Vector &left, int64_t delta, idx_t count);
static void IsNotNull(Vector &arg, Vector &result, idx_t count);
static void IsNull(Vector &input, Vector &result, idx_t count);
static bool HasNull(Vector &input, idx_t count);
static bool HasNotNull(Vector &input, idx_t count);
static idx_t CountNotNull(Vector &input, const idx_t count);
static void And(Vector &left, Vector &right, Vector &result, idx_t count);
static void Or(Vector &left, Vector &right, Vector &result, idx_t count);
static void Not(Vector &left, Vector &result, idx_t count);
static void Equals(Vector &left, Vector &right, Vector &result, idx_t count);
static void NotEquals(Vector &left, Vector &right, Vector &result, idx_t count);
static void GreaterThan(Vector &left, Vector &right, Vector &result, idx_t count);
static void GreaterThanEquals(Vector &left, Vector &right, Vector &result, idx_t count);
static void LessThan(Vector &left, Vector &right, Vector &result, idx_t count);
static void LessThanEquals(Vector &left, Vector &right, Vector &result, idx_t count);
static void DistinctFrom(Vector &left, Vector &right, Vector &result, idx_t count);
static void NotDistinctFrom(Vector &left, Vector &right, Vector &result, idx_t count);
static void DistinctGreaterThan(Vector &left, Vector &right, Vector &result, idx_t count);
static void DistinctGreaterThanEquals(Vector &left, Vector &right, Vector &result, idx_t count);
static void DistinctLessThan(Vector &left, Vector &right, Vector &result, idx_t count);
static void DistinctLessThanEquals(Vector &left, Vector &right, Vector &result, idx_t count);
static idx_t Equals(Vector &left, Vector &right, const SelectionVector *sel, idx_t count, SelectionVector *true_sel,
SelectionVector *false_sel);
static idx_t NotEquals(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t GreaterThan(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t GreaterThanEquals(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t LessThan(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t LessThanEquals(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t DistinctFrom(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t NotDistinctFrom(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t DistinctGreaterThan(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t DistinctGreaterThanEquals(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t DistinctLessThan(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t DistinctLessThanEquals(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t DistinctGreaterThanNullsFirst(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t DistinctLessThanNullsFirst(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t NestedNotEquals(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static idx_t NestedEquals(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel);
static void Hash(Vector &input, Vector &hashes, idx_t count);
static void Hash(Vector &input, Vector &hashes, const SelectionVector &rsel, idx_t count);
static void CombineHash(Vector &hashes, Vector &input, idx_t count);
static void CombineHash(Vector &hashes, Vector &input, const SelectionVector &rsel, idx_t count);
static void GenerateSequence(Vector &result, idx_t count, int64_t start = 0, int64_t increment = 1);
static void GenerateSequence(Vector &result, idx_t count, const SelectionVector &sel, int64_t start = 0,
int64_t increment = 1);
DUCKDB_API static bool TryCast(CastFunctionSet &set, GetCastFunctionInput &input, Vector &source, Vector &result,
idx_t count, string *error_message, bool strict = false);
DUCKDB_API static bool DefaultTryCast(Vector &source, Vector &result, idx_t count, string *error_message,
bool strict = false);
DUCKDB_API static bool TryCast(ClientContext &context, Vector &source, Vector &result, idx_t count,
string *error_message, bool strict = false);
DUCKDB_API static void Cast(ClientContext &context, Vector &source, Vector &result, idx_t count,
bool strict = false);
DUCKDB_API static void DefaultCast(Vector &source, Vector &result, idx_t count, bool strict = false);
static void Copy(const Vector &source, Vector &target, idx_t source_count, idx_t source_offset,
idx_t target_offset);
static void Copy(const Vector &source, Vector &target, const SelectionVector &sel, idx_t source_count,
idx_t source_offset, idx_t target_offset);
static void WriteToStorage(Vector &source, idx_t count, data_ptr_t target);
static void ReadFromStorage(data_ptr_t source, idx_t count, Vector &result);
};
}
#include <functional>
namespace duckdb {
struct DefaultNullCheckOperator {
template <class LEFT_TYPE, class RIGHT_TYPE>
static inline bool Operation(LEFT_TYPE left, RIGHT_TYPE right) {
return false;
}
};
struct BinaryStandardOperatorWrapper {
template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, ValidityMask &mask, idx_t idx) {
return OP::template Operation<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(left, right);
}
static bool AddsNulls() {
return false;
}
};
struct BinarySingleArgumentOperatorWrapper {
template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, ValidityMask &mask, idx_t idx) {
return OP::template Operation<LEFT_TYPE>(left, right);
}
static bool AddsNulls() {
return false;
}
};
struct BinaryLambdaWrapper {
template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, ValidityMask &mask, idx_t idx) {
return fun(left, right);
}
static bool AddsNulls() {
return false;
}
};
struct BinaryLambdaWrapperWithNulls {
template <class FUNC, class OP, class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(FUNC fun, LEFT_TYPE left, RIGHT_TYPE right, ValidityMask &mask, idx_t idx) {
return fun(left, right, mask, idx);
}
static bool AddsNulls() {
return true;
}
};
struct BinaryExecutor {
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
static void ExecuteFlatLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
RESULT_TYPE *__restrict result_data, idx_t count, ValidityMask &mask, FUNC fun) {
if (!LEFT_CONSTANT) {
ASSERT_RESTRICT(ldata, ldata + count, result_data, result_data + count);
}
if (!RIGHT_CONSTANT) {
ASSERT_RESTRICT(rdata, rdata + count, result_data, result_data + count);
}
if (!mask.AllValid()) {
idx_t base_idx = 0;
auto entry_count = ValidityMask::EntryCount(count);
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
auto validity_entry = mask.GetValidityEntry(entry_idx);
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
if (ValidityMask::AllValid(validity_entry)) {
for (; base_idx < next; base_idx++) {
auto lentry = ldata[LEFT_CONSTANT ? 0 : base_idx];
auto rentry = rdata[RIGHT_CONSTANT ? 0 : base_idx];
result_data[base_idx] =
OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
fun, lentry, rentry, mask, base_idx);
}
} else if (ValidityMask::NoneValid(validity_entry)) {
base_idx = next;
continue;
} else {
idx_t start = base_idx;
for (; base_idx < next; base_idx++) {
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
auto lentry = ldata[LEFT_CONSTANT ? 0 : base_idx];
auto rentry = rdata[RIGHT_CONSTANT ? 0 : base_idx];
result_data[base_idx] =
OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
fun, lentry, rentry, mask, base_idx);
}
}
}
}
} else {
for (idx_t i = 0; i < count; i++) {
auto lentry = ldata[LEFT_CONSTANT ? 0 : i];
auto rentry = rdata[RIGHT_CONSTANT ? 0 : i];
result_data[i] = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
fun, lentry, rentry, mask, i);
}
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC>
static void ExecuteConstant(Vector &left, Vector &right, Vector &result, FUNC fun) {
result.SetVectorType(VectorType::CONSTANT_VECTOR);
auto ldata = ConstantVector::GetData<LEFT_TYPE>(left);
auto rdata = ConstantVector::GetData<RIGHT_TYPE>(right);
auto result_data = ConstantVector::GetData<RESULT_TYPE>(result);
if (ConstantVector::IsNull(left) || ConstantVector::IsNull(right)) {
ConstantVector::SetNull(result, true);
return;
}
*result_data = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
fun, *ldata, *rdata, ConstantVector::Validity(result), 0);
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC,
bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
static void ExecuteFlat(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
auto ldata = FlatVector::GetData<LEFT_TYPE>(left);
auto rdata = FlatVector::GetData<RIGHT_TYPE>(right);
if ((LEFT_CONSTANT && ConstantVector::IsNull(left)) || (RIGHT_CONSTANT && ConstantVector::IsNull(right))) {
result.SetVectorType(VectorType::CONSTANT_VECTOR);
ConstantVector::SetNull(result, true);
return;
}
result.SetVectorType(VectorType::FLAT_VECTOR);
auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
auto &result_validity = FlatVector::Validity(result);
if (LEFT_CONSTANT) {
if (OPWRAPPER::AddsNulls()) {
result_validity.Copy(FlatVector::Validity(right), count);
} else {
FlatVector::SetValidity(result, FlatVector::Validity(right));
}
} else if (RIGHT_CONSTANT) {
if (OPWRAPPER::AddsNulls()) {
result_validity.Copy(FlatVector::Validity(left), count);
} else {
FlatVector::SetValidity(result, FlatVector::Validity(left));
}
} else {
if (OPWRAPPER::AddsNulls()) {
result_validity.Copy(FlatVector::Validity(left), count);
if (result_validity.AllValid()) {
result_validity.Copy(FlatVector::Validity(right), count);
} else {
result_validity.Combine(FlatVector::Validity(right), count);
}
} else {
FlatVector::SetValidity(result, FlatVector::Validity(left));
result_validity.Combine(FlatVector::Validity(right), count);
}
}
ExecuteFlatLoop<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, LEFT_CONSTANT, RIGHT_CONSTANT>(
ldata, rdata, result_data, count, result_validity, fun);
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC>
static void ExecuteGenericLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
RESULT_TYPE *__restrict result_data, const SelectionVector *__restrict lsel,
const SelectionVector *__restrict rsel, idx_t count, ValidityMask &lvalidity,
ValidityMask &rvalidity, ValidityMask &result_validity, FUNC fun) {
if (!lvalidity.AllValid() || !rvalidity.AllValid()) {
for (idx_t i = 0; i < count; i++) {
auto lindex = lsel->get_index(i);
auto rindex = rsel->get_index(i);
if (lvalidity.RowIsValid(lindex) && rvalidity.RowIsValid(rindex)) {
auto lentry = ldata[lindex];
auto rentry = rdata[rindex];
result_data[i] = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
fun, lentry, rentry, result_validity, i);
} else {
result_validity.SetInvalid(i);
}
}
} else {
for (idx_t i = 0; i < count; i++) {
auto lentry = ldata[lsel->get_index(i)];
auto rentry = rdata[rsel->get_index(i)];
result_data[i] = OPWRAPPER::template Operation<FUNC, OP, LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE>(
fun, lentry, rentry, result_validity, i);
}
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC>
static void ExecuteGeneric(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
UnifiedVectorFormat ldata, rdata;
left.ToUnifiedFormat(count, ldata);
right.ToUnifiedFormat(count, rdata);
result.SetVectorType(VectorType::FLAT_VECTOR);
auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
ExecuteGenericLoop<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC>(
(LEFT_TYPE *)ldata.data, (RIGHT_TYPE *)rdata.data, result_data, ldata.sel, rdata.sel, count, ldata.validity,
rdata.validity, FlatVector::Validity(result), fun);
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP, class FUNC>
static void ExecuteSwitch(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
auto left_vector_type = left.GetVectorType();
auto right_vector_type = right.GetVectorType();
if (left_vector_type == VectorType::CONSTANT_VECTOR && right_vector_type == VectorType::CONSTANT_VECTOR) {
ExecuteConstant<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC>(left, right, result, fun);
} else if (left_vector_type == VectorType::FLAT_VECTOR && right_vector_type == VectorType::CONSTANT_VECTOR) {
ExecuteFlat<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, false, true>(left, right, result,
count, fun);
} else if (left_vector_type == VectorType::CONSTANT_VECTOR && right_vector_type == VectorType::FLAT_VECTOR) {
ExecuteFlat<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, true, false>(left, right, result,
count, fun);
} else if (left_vector_type == VectorType::FLAT_VECTOR && right_vector_type == VectorType::FLAT_VECTOR) {
ExecuteFlat<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC, false, false>(left, right, result,
count, fun);
} else {
ExecuteGeneric<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, FUNC>(left, right, result, count, fun);
}
}
public:
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE,
class FUNC = std::function<RESULT_TYPE(LEFT_TYPE, RIGHT_TYPE)>>
static void Execute(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
ExecuteSwitch<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, BinaryLambdaWrapper, bool, FUNC>(left, right, result, count,
fun);
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OP,
class OPWRAPPER = BinarySingleArgumentOperatorWrapper>
static void Execute(Vector &left, Vector &right, Vector &result, idx_t count) {
ExecuteSwitch<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, OPWRAPPER, OP, bool>(left, right, result, count, false);
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE, class OP>
static void ExecuteStandard(Vector &left, Vector &right, Vector &result, idx_t count) {
ExecuteSwitch<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, BinaryStandardOperatorWrapper, OP, bool>(left, right, result,
count, false);
}
template <class LEFT_TYPE, class RIGHT_TYPE, class RESULT_TYPE,
class FUNC = std::function<RESULT_TYPE(LEFT_TYPE, RIGHT_TYPE, ValidityMask &, idx_t)>>
static void ExecuteWithNulls(Vector &left, Vector &right, Vector &result, idx_t count, FUNC fun) {
ExecuteSwitch<LEFT_TYPE, RIGHT_TYPE, RESULT_TYPE, BinaryLambdaWrapperWithNulls, bool, FUNC>(left, right, result,
count, fun);
}
public:
template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
static idx_t SelectConstant(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel) {
auto ldata = ConstantVector::GetData<LEFT_TYPE>(left);
auto rdata = ConstantVector::GetData<RIGHT_TYPE>(right);
if (ConstantVector::IsNull(left) || ConstantVector::IsNull(right) || !OP::Operation(*ldata, *rdata)) {
if (false_sel) {
for (idx_t i = 0; i < count; i++) {
false_sel->set_index(i, sel->get_index(i));
}
}
return 0;
} else {
if (true_sel) {
for (idx_t i = 0; i < count; i++) {
true_sel->set_index(i, sel->get_index(i));
}
}
return count;
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool LEFT_CONSTANT, bool RIGHT_CONSTANT, bool HAS_TRUE_SEL,
bool HAS_FALSE_SEL>
static inline idx_t SelectFlatLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
const SelectionVector *sel, idx_t count, ValidityMask &validity_mask,
SelectionVector *true_sel, SelectionVector *false_sel) {
idx_t true_count = 0, false_count = 0;
idx_t base_idx = 0;
auto entry_count = ValidityMask::EntryCount(count);
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
auto validity_entry = validity_mask.GetValidityEntry(entry_idx);
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
if (ValidityMask::AllValid(validity_entry)) {
for (; base_idx < next; base_idx++) {
idx_t result_idx = sel->get_index(base_idx);
idx_t lidx = LEFT_CONSTANT ? 0 : base_idx;
idx_t ridx = RIGHT_CONSTANT ? 0 : base_idx;
bool comparison_result = OP::Operation(ldata[lidx], rdata[ridx]);
if (HAS_TRUE_SEL) {
true_sel->set_index(true_count, result_idx);
true_count += comparison_result;
}
if (HAS_FALSE_SEL) {
false_sel->set_index(false_count, result_idx);
false_count += !comparison_result;
}
}
} else if (ValidityMask::NoneValid(validity_entry)) {
if (HAS_FALSE_SEL) {
for (; base_idx < next; base_idx++) {
idx_t result_idx = sel->get_index(base_idx);
false_sel->set_index(false_count, result_idx);
false_count++;
}
}
base_idx = next;
continue;
} else {
idx_t start = base_idx;
for (; base_idx < next; base_idx++) {
idx_t result_idx = sel->get_index(base_idx);
idx_t lidx = LEFT_CONSTANT ? 0 : base_idx;
idx_t ridx = RIGHT_CONSTANT ? 0 : base_idx;
bool comparison_result = ValidityMask::RowIsValid(validity_entry, base_idx - start) &&
OP::Operation(ldata[lidx], rdata[ridx]);
if (HAS_TRUE_SEL) {
true_sel->set_index(true_count, result_idx);
true_count += comparison_result;
}
if (HAS_FALSE_SEL) {
false_sel->set_index(false_count, result_idx);
false_count += !comparison_result;
}
}
}
}
if (HAS_TRUE_SEL) {
return true_count;
} else {
return count - false_count;
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
static inline idx_t SelectFlatLoopSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
const SelectionVector *sel, idx_t count, ValidityMask &mask,
SelectionVector *true_sel, SelectionVector *false_sel) {
if (true_sel && false_sel) {
return SelectFlatLoop<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, true, true>(
ldata, rdata, sel, count, mask, true_sel, false_sel);
} else if (true_sel) {
return SelectFlatLoop<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, true, false>(
ldata, rdata, sel, count, mask, true_sel, false_sel);
} else {
D_ASSERT(false_sel);
return SelectFlatLoop<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT, false, true>(
ldata, rdata, sel, count, mask, true_sel, false_sel);
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool LEFT_CONSTANT, bool RIGHT_CONSTANT>
static idx_t SelectFlat(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel) {
auto ldata = FlatVector::GetData<LEFT_TYPE>(left);
auto rdata = FlatVector::GetData<RIGHT_TYPE>(right);
if (LEFT_CONSTANT && ConstantVector::IsNull(left)) {
if (false_sel) {
for (idx_t i = 0; i < count; i++) {
false_sel->set_index(i, sel->get_index(i));
}
}
return 0;
}
if (RIGHT_CONSTANT && ConstantVector::IsNull(right)) {
if (false_sel) {
for (idx_t i = 0; i < count; i++) {
false_sel->set_index(i, sel->get_index(i));
}
}
return 0;
}
if (LEFT_CONSTANT) {
return SelectFlatLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT>(
ldata, rdata, sel, count, FlatVector::Validity(right), true_sel, false_sel);
} else if (RIGHT_CONSTANT) {
return SelectFlatLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT>(
ldata, rdata, sel, count, FlatVector::Validity(left), true_sel, false_sel);
} else {
ValidityMask combined_mask = FlatVector::Validity(left);
combined_mask.Combine(FlatVector::Validity(right), count);
return SelectFlatLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP, LEFT_CONSTANT, RIGHT_CONSTANT>(
ldata, rdata, sel, count, combined_mask, true_sel, false_sel);
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool NO_NULL, bool HAS_TRUE_SEL, bool HAS_FALSE_SEL>
static inline idx_t
SelectGenericLoop(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata, const SelectionVector *__restrict lsel,
const SelectionVector *__restrict rsel, const SelectionVector *__restrict result_sel, idx_t count,
ValidityMask &lvalidity, ValidityMask &rvalidity, SelectionVector *true_sel,
SelectionVector *false_sel) {
idx_t true_count = 0, false_count = 0;
for (idx_t i = 0; i < count; i++) {
auto result_idx = result_sel->get_index(i);
auto lindex = lsel->get_index(i);
auto rindex = rsel->get_index(i);
if ((NO_NULL || (lvalidity.RowIsValid(lindex) && rvalidity.RowIsValid(rindex))) &&
OP::Operation(ldata[lindex], rdata[rindex])) {
if (HAS_TRUE_SEL) {
true_sel->set_index(true_count++, result_idx);
}
} else {
if (HAS_FALSE_SEL) {
false_sel->set_index(false_count++, result_idx);
}
}
}
if (HAS_TRUE_SEL) {
return true_count;
} else {
return count - false_count;
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP, bool NO_NULL>
static inline idx_t
SelectGenericLoopSelSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
const SelectionVector *__restrict lsel, const SelectionVector *__restrict rsel,
const SelectionVector *__restrict result_sel, idx_t count, ValidityMask &lvalidity,
ValidityMask &rvalidity, SelectionVector *true_sel, SelectionVector *false_sel) {
if (true_sel && false_sel) {
return SelectGenericLoop<LEFT_TYPE, RIGHT_TYPE, OP, NO_NULL, true, true>(
ldata, rdata, lsel, rsel, result_sel, count, lvalidity, rvalidity, true_sel, false_sel);
} else if (true_sel) {
return SelectGenericLoop<LEFT_TYPE, RIGHT_TYPE, OP, NO_NULL, true, false>(
ldata, rdata, lsel, rsel, result_sel, count, lvalidity, rvalidity, true_sel, false_sel);
} else {
D_ASSERT(false_sel);
return SelectGenericLoop<LEFT_TYPE, RIGHT_TYPE, OP, NO_NULL, false, true>(
ldata, rdata, lsel, rsel, result_sel, count, lvalidity, rvalidity, true_sel, false_sel);
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
static inline idx_t
SelectGenericLoopSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restrict rdata,
const SelectionVector *__restrict lsel, const SelectionVector *__restrict rsel,
const SelectionVector *__restrict result_sel, idx_t count, ValidityMask &lvalidity,
ValidityMask &rvalidity, SelectionVector *true_sel, SelectionVector *false_sel) {
if (!lvalidity.AllValid() || !rvalidity.AllValid()) {
return SelectGenericLoopSelSwitch<LEFT_TYPE, RIGHT_TYPE, OP, false>(
ldata, rdata, lsel, rsel, result_sel, count, lvalidity, rvalidity, true_sel, false_sel);
} else {
return SelectGenericLoopSelSwitch<LEFT_TYPE, RIGHT_TYPE, OP, true>(
ldata, rdata, lsel, rsel, result_sel, count, lvalidity, rvalidity, true_sel, false_sel);
}
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
static idx_t SelectGeneric(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel) {
UnifiedVectorFormat ldata, rdata;
left.ToUnifiedFormat(count, ldata);
right.ToUnifiedFormat(count, rdata);
return SelectGenericLoopSwitch<LEFT_TYPE, RIGHT_TYPE, OP>((LEFT_TYPE *)ldata.data, (RIGHT_TYPE *)rdata.data,
ldata.sel, rdata.sel, sel, count, ldata.validity,
rdata.validity, true_sel, false_sel);
}
template <class LEFT_TYPE, class RIGHT_TYPE, class OP>
static idx_t Select(Vector &left, Vector &right, const SelectionVector *sel, idx_t count, SelectionVector *true_sel,
SelectionVector *false_sel) {
if (!sel) {
sel = FlatVector::IncrementalSelectionVector();
}
if (left.GetVectorType() == VectorType::CONSTANT_VECTOR &&
right.GetVectorType() == VectorType::CONSTANT_VECTOR) {
return SelectConstant<LEFT_TYPE, RIGHT_TYPE, OP>(left, right, sel, count, true_sel, false_sel);
} else if (left.GetVectorType() == VectorType::CONSTANT_VECTOR &&
right.GetVectorType() == VectorType::FLAT_VECTOR) {
return SelectFlat<LEFT_TYPE, RIGHT_TYPE, OP, true, false>(left, right, sel, count, true_sel, false_sel);
} else if (left.GetVectorType() == VectorType::FLAT_VECTOR &&
right.GetVectorType() == VectorType::CONSTANT_VECTOR) {
return SelectFlat<LEFT_TYPE, RIGHT_TYPE, OP, false, true>(left, right, sel, count, true_sel, false_sel);
} else if (left.GetVectorType() == VectorType::FLAT_VECTOR &&
right.GetVectorType() == VectorType::FLAT_VECTOR) {
return SelectFlat<LEFT_TYPE, RIGHT_TYPE, OP, false, false>(left, right, sel, count, true_sel, false_sel);
} else {
return SelectGeneric<LEFT_TYPE, RIGHT_TYPE, OP>(left, right, sel, count, true_sel, false_sel);
}
}
};
}
#include <functional>
namespace duckdb {
template <class OP>
struct TernaryStandardOperatorWrapper {
template <class FUN, class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(FUN fun, A_TYPE a, B_TYPE b, C_TYPE c, ValidityMask &mask, idx_t idx) {
return OP::template Operation<A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE>(a, b, c);
}
};
struct TernaryLambdaWrapper {
template <class FUN, class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(FUN fun, A_TYPE a, B_TYPE b, C_TYPE c, ValidityMask &mask, idx_t idx) {
return fun(a, b, c);
}
};
struct TernaryLambdaWrapperWithNulls {
template <class FUN, class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(FUN fun, A_TYPE a, B_TYPE b, C_TYPE c, ValidityMask &mask, idx_t idx) {
return fun(a, b, c, mask, idx);
}
};
struct TernaryExecutor {
private:
template <class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE, class OPWRAPPER, class FUN>
static inline void ExecuteLoop(A_TYPE *__restrict adata, B_TYPE *__restrict bdata, C_TYPE *__restrict cdata,
RESULT_TYPE *__restrict result_data, idx_t count, const SelectionVector &asel,
const SelectionVector &bsel, const SelectionVector &csel, ValidityMask &avalidity,
ValidityMask &bvalidity, ValidityMask &cvalidity, ValidityMask &result_validity,
FUN fun) {
if (!avalidity.AllValid() || !bvalidity.AllValid() || !cvalidity.AllValid()) {
for (idx_t i = 0; i < count; i++) {
auto aidx = asel.get_index(i);
auto bidx = bsel.get_index(i);
auto cidx = csel.get_index(i);
if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx) && cvalidity.RowIsValid(cidx)) {
result_data[i] = OPWRAPPER::template Operation<FUN, A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE>(
fun, adata[aidx], bdata[bidx], cdata[cidx], result_validity, i);
} else {
result_validity.SetInvalid(i);
}
}
} else {
for (idx_t i = 0; i < count; i++) {
auto aidx = asel.get_index(i);
auto bidx = bsel.get_index(i);
auto cidx = csel.get_index(i);
result_data[i] = OPWRAPPER::template Operation<FUN, A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE>(
fun, adata[aidx], bdata[bidx], cdata[cidx], result_validity, i);
}
}
}
public:
template <class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE, class OPWRAPPER, class FUN>
static void ExecuteGeneric(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count, FUN fun) {
if (a.GetVectorType() == VectorType::CONSTANT_VECTOR && b.GetVectorType() == VectorType::CONSTANT_VECTOR &&
c.GetVectorType() == VectorType::CONSTANT_VECTOR) {
result.SetVectorType(VectorType::CONSTANT_VECTOR);
if (ConstantVector::IsNull(a) || ConstantVector::IsNull(b) || ConstantVector::IsNull(c)) {
ConstantVector::SetNull(result, true);
} else {
auto adata = ConstantVector::GetData<A_TYPE>(a);
auto bdata = ConstantVector::GetData<B_TYPE>(b);
auto cdata = ConstantVector::GetData<C_TYPE>(c);
auto result_data = ConstantVector::GetData<RESULT_TYPE>(result);
auto &result_validity = ConstantVector::Validity(result);
result_data[0] = OPWRAPPER::template Operation<FUN, A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE>(
fun, adata[0], bdata[0], cdata[0], result_validity, 0);
}
} else {
result.SetVectorType(VectorType::FLAT_VECTOR);
UnifiedVectorFormat adata, bdata, cdata;
a.ToUnifiedFormat(count, adata);
b.ToUnifiedFormat(count, bdata);
c.ToUnifiedFormat(count, cdata);
ExecuteLoop<A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE, OPWRAPPER>(
(A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data,
FlatVector::GetData<RESULT_TYPE>(result), count, *adata.sel, *bdata.sel, *cdata.sel, adata.validity,
bdata.validity, cdata.validity, FlatVector::Validity(result), fun);
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE,
class FUN = std::function<RESULT_TYPE(A_TYPE, B_TYPE, C_TYPE)>>
static void Execute(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count, FUN fun) {
ExecuteGeneric<A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE, TernaryLambdaWrapper, FUN>(a, b, c, result, count, fun);
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE, class OP>
static void ExecuteStandard(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count) {
ExecuteGeneric<A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE, TernaryStandardOperatorWrapper<OP>, bool>(a, b, c, result,
count, false);
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class RESULT_TYPE,
class FUN = std::function<RESULT_TYPE(A_TYPE, B_TYPE, C_TYPE, ValidityMask &, idx_t)>>
static void ExecuteWithNulls(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count, FUN fun) {
ExecuteGeneric<A_TYPE, B_TYPE, C_TYPE, RESULT_TYPE, TernaryLambdaWrapperWithNulls, FUN>(a, b, c, result, count,
fun);
}
private:
template <class A_TYPE, class B_TYPE, class C_TYPE, class OP, bool NO_NULL, bool HAS_TRUE_SEL, bool HAS_FALSE_SEL>
static inline idx_t SelectLoop(A_TYPE *__restrict adata, B_TYPE *__restrict bdata, C_TYPE *__restrict cdata,
const SelectionVector *result_sel, idx_t count, const SelectionVector &asel,
const SelectionVector &bsel, const SelectionVector &csel, ValidityMask &avalidity,
ValidityMask &bvalidity, ValidityMask &cvalidity, SelectionVector *true_sel,
SelectionVector *false_sel) {
idx_t true_count = 0, false_count = 0;
for (idx_t i = 0; i < count; i++) {
auto result_idx = result_sel->get_index(i);
auto aidx = asel.get_index(i);
auto bidx = bsel.get_index(i);
auto cidx = csel.get_index(i);
bool comparison_result =
(NO_NULL || (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx) && cvalidity.RowIsValid(cidx))) &&
OP::Operation(adata[aidx], bdata[bidx], cdata[cidx]);
if (HAS_TRUE_SEL) {
true_sel->set_index(true_count, result_idx);
true_count += comparison_result;
}
if (HAS_FALSE_SEL) {
false_sel->set_index(false_count, result_idx);
false_count += !comparison_result;
}
}
if (HAS_TRUE_SEL) {
return true_count;
} else {
return count - false_count;
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class OP, bool NO_NULL>
static inline idx_t SelectLoopSelSwitch(UnifiedVectorFormat &adata, UnifiedVectorFormat &bdata,
UnifiedVectorFormat &cdata, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel) {
if (true_sel && false_sel) {
return SelectLoop<A_TYPE, B_TYPE, C_TYPE, OP, NO_NULL, true, true>(
(A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data, sel, count, *adata.sel, *bdata.sel,
*cdata.sel, adata.validity, bdata.validity, cdata.validity, true_sel, false_sel);
} else if (true_sel) {
return SelectLoop<A_TYPE, B_TYPE, C_TYPE, OP, NO_NULL, true, false>(
(A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data, sel, count, *adata.sel, *bdata.sel,
*cdata.sel, adata.validity, bdata.validity, cdata.validity, true_sel, false_sel);
} else {
D_ASSERT(false_sel);
return SelectLoop<A_TYPE, B_TYPE, C_TYPE, OP, NO_NULL, false, true>(
(A_TYPE *)adata.data, (B_TYPE *)bdata.data, (C_TYPE *)cdata.data, sel, count, *adata.sel, *bdata.sel,
*cdata.sel, adata.validity, bdata.validity, cdata.validity, true_sel, false_sel);
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class OP>
static inline idx_t SelectLoopSwitch(UnifiedVectorFormat &adata, UnifiedVectorFormat &bdata,
UnifiedVectorFormat &cdata, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel) {
if (!adata.validity.AllValid() || !bdata.validity.AllValid() || !cdata.validity.AllValid()) {
return SelectLoopSelSwitch<A_TYPE, B_TYPE, C_TYPE, OP, false>(adata, bdata, cdata, sel, count, true_sel,
false_sel);
} else {
return SelectLoopSelSwitch<A_TYPE, B_TYPE, C_TYPE, OP, true>(adata, bdata, cdata, sel, count, true_sel,
false_sel);
}
}
public:
template <class A_TYPE, class B_TYPE, class C_TYPE, class OP>
static idx_t Select(Vector &a, Vector &b, Vector &c, const SelectionVector *sel, idx_t count,
SelectionVector *true_sel, SelectionVector *false_sel) {
if (!sel) {
sel = FlatVector::IncrementalSelectionVector();
}
UnifiedVectorFormat adata, bdata, cdata;
a.ToUnifiedFormat(count, adata);
b.ToUnifiedFormat(count, bdata);
c.ToUnifiedFormat(count, cdata);
return SelectLoopSwitch<A_TYPE, B_TYPE, C_TYPE, OP>(adata, bdata, cdata, sel, count, true_sel, false_sel);
}
};
}
#include <functional>
namespace duckdb {
struct UnaryOperatorWrapper {
template <class OP, class INPUT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
return OP::template Operation<INPUT_TYPE, RESULT_TYPE>(input);
}
};
struct UnaryLambdaWrapper {
template <class FUNC, class INPUT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
auto fun = (FUNC *)dataptr;
return (*fun)(input);
}
};
struct GenericUnaryWrapper {
template <class OP, class INPUT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
return OP::template Operation<INPUT_TYPE, RESULT_TYPE>(input, mask, idx, dataptr);
}
};
struct UnaryLambdaWrapperWithNulls {
template <class FUNC, class INPUT_TYPE, class RESULT_TYPE>
static inline RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
auto fun = (FUNC *)dataptr;
return (*fun)(input, mask, idx);
}
};
template <class OP>
struct UnaryStringOperator {
template <class INPUT_TYPE, class RESULT_TYPE>
static RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
auto vector = (Vector *)dataptr;
return OP::template Operation<INPUT_TYPE, RESULT_TYPE>(input, *vector);
}
};
struct UnaryExecutor {
private:
template <class INPUT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP>
static inline void ExecuteLoop(INPUT_TYPE *__restrict ldata, RESULT_TYPE *__restrict result_data, idx_t count,
const SelectionVector *__restrict sel_vector, ValidityMask &mask,
ValidityMask &result_mask, void *dataptr, bool adds_nulls) {
#ifdef DEBUG
idx_t max_index = 0;
for (idx_t i = 0; i < count; i++) {
auto idx = sel_vector->get_index(i);
max_index = MaxValue(max_index, idx);
}
ASSERT_RESTRICT(ldata, ldata + max_index, result_data, result_data + count);
#endif
if (!mask.AllValid()) {
result_mask.EnsureWritable();
for (idx_t i = 0; i < count; i++) {
auto idx = sel_vector->get_index(i);
if (mask.RowIsValidUnsafe(idx)) {
result_data[i] =
OPWRAPPER::template Operation<OP, INPUT_TYPE, RESULT_TYPE>(ldata[idx], result_mask, i, dataptr);
} else {
result_mask.SetInvalid(i);
}
}
} else {
if (adds_nulls) {
result_mask.EnsureWritable();
}
for (idx_t i = 0; i < count; i++) {
auto idx = sel_vector->get_index(i);
result_data[i] =
OPWRAPPER::template Operation<OP, INPUT_TYPE, RESULT_TYPE>(ldata[idx], result_mask, i, dataptr);
}
}
}
template <class INPUT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP>
static inline void ExecuteFlat(INPUT_TYPE *__restrict ldata, RESULT_TYPE *__restrict result_data, idx_t count,
ValidityMask &mask, ValidityMask &result_mask, void *dataptr, bool adds_nulls) {
ASSERT_RESTRICT(ldata, ldata + count, result_data, result_data + count);
if (!mask.AllValid()) {
if (!adds_nulls) {
result_mask.Initialize(mask);
} else {
result_mask.Copy(mask, count);
}
idx_t base_idx = 0;
auto entry_count = ValidityMask::EntryCount(count);
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
auto validity_entry = mask.GetValidityEntry(entry_idx);
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
if (ValidityMask::AllValid(validity_entry)) {
for (; base_idx < next; base_idx++) {
result_data[base_idx] = OPWRAPPER::template Operation<OP, INPUT_TYPE, RESULT_TYPE>(
ldata[base_idx], result_mask, base_idx, dataptr);
}
} else if (ValidityMask::NoneValid(validity_entry)) {
base_idx = next;
continue;
} else {
idx_t start = base_idx;
for (; base_idx < next; base_idx++) {
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
D_ASSERT(mask.RowIsValid(base_idx));
result_data[base_idx] = OPWRAPPER::template Operation<OP, INPUT_TYPE, RESULT_TYPE>(
ldata[base_idx], result_mask, base_idx, dataptr);
}
}
}
}
} else {
if (adds_nulls) {
result_mask.EnsureWritable();
}
for (idx_t i = 0; i < count; i++) {
result_data[i] =
OPWRAPPER::template Operation<OP, INPUT_TYPE, RESULT_TYPE>(ldata[i], result_mask, i, dataptr);
}
}
}
template <class INPUT_TYPE, class RESULT_TYPE, class OPWRAPPER, class OP>
static inline void ExecuteStandard(Vector &input, Vector &result, idx_t count, void *dataptr, bool adds_nulls) {
switch (input.GetVectorType()) {
case VectorType::CONSTANT_VECTOR: {
result.SetVectorType(VectorType::CONSTANT_VECTOR);
auto result_data = ConstantVector::GetData<RESULT_TYPE>(result);
auto ldata = ConstantVector::GetData<INPUT_TYPE>(input);
if (ConstantVector::IsNull(input)) {
ConstantVector::SetNull(result, true);
} else {
ConstantVector::SetNull(result, false);
*result_data = OPWRAPPER::template Operation<OP, INPUT_TYPE, RESULT_TYPE>(
*ldata, ConstantVector::Validity(result), 0, dataptr);
}
break;
}
case VectorType::FLAT_VECTOR: {
result.SetVectorType(VectorType::FLAT_VECTOR);
auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
auto ldata = FlatVector::GetData<INPUT_TYPE>(input);
ExecuteFlat<INPUT_TYPE, RESULT_TYPE, OPWRAPPER, OP>(ldata, result_data, count, FlatVector::Validity(input),
FlatVector::Validity(result), dataptr, adds_nulls);
break;
}
default: {
UnifiedVectorFormat vdata;
input.ToUnifiedFormat(count, vdata);
result.SetVectorType(VectorType::FLAT_VECTOR);
auto result_data = FlatVector::GetData<RESULT_TYPE>(result);
auto ldata = (INPUT_TYPE *)vdata.data;
ExecuteLoop<INPUT_TYPE, RESULT_TYPE, OPWRAPPER, OP>(ldata, result_data, count, vdata.sel, vdata.validity,
FlatVector::Validity(result), dataptr, adds_nulls);
break;
}
}
}
public:
template <class INPUT_TYPE, class RESULT_TYPE, class OP>
static void Execute(Vector &input, Vector &result, idx_t count) {
ExecuteStandard<INPUT_TYPE, RESULT_TYPE, UnaryOperatorWrapper, OP>(input, result, count, nullptr, false);
}
template <class INPUT_TYPE, class RESULT_TYPE, class FUNC = std::function<RESULT_TYPE(INPUT_TYPE)>>
static void Execute(Vector &input, Vector &result, idx_t count, FUNC fun) {
ExecuteStandard<INPUT_TYPE, RESULT_TYPE, UnaryLambdaWrapper, FUNC>(input, result, count, (void *)&fun, false);
}
template <class INPUT_TYPE, class RESULT_TYPE, class OP>
static void GenericExecute(Vector &input, Vector &result, idx_t count, void *dataptr, bool adds_nulls = false) {
ExecuteStandard<INPUT_TYPE, RESULT_TYPE, GenericUnaryWrapper, OP>(input, result, count, dataptr, adds_nulls);
}
template <class INPUT_TYPE, class RESULT_TYPE,
class FUNC = std::function<RESULT_TYPE(INPUT_TYPE, ValidityMask &, idx_t)>>
static void ExecuteWithNulls(Vector &input, Vector &result, idx_t count, FUNC fun) {
ExecuteStandard<INPUT_TYPE, RESULT_TYPE, UnaryLambdaWrapperWithNulls, FUNC>(input, result, count, (void *)&fun,
true);
}
template <class INPUT_TYPE, class RESULT_TYPE, class OP>
static void ExecuteString(Vector &input, Vector &result, idx_t count) {
UnaryExecutor::GenericExecute<string_t, string_t, UnaryStringOperator<OP>>(input, result, count,
(void *)&result);
}
};
}
#include <chrono>
namespace duckdb {
using std::chrono::duration;
using std::chrono::duration_cast;
using std::chrono::high_resolution_clock;
using std::chrono::milliseconds;
using std::chrono::system_clock;
using std::chrono::time_point;
}
namespace duckdb {
class CycleCounter {
friend struct ExpressionInfo;
friend struct ExpressionRootInfo;
static constexpr int SAMPLING_RATE = 50;
public:
CycleCounter() {
}
void BeginSample() {
if (current_count >= next_sample) {
tmp = Tick();
}
}
void EndSample(int chunk_size) {
if (current_count >= next_sample) {
time += Tick() - tmp;
}
if (current_count >= next_sample) {
next_sample = SAMPLING_RATE;
++sample_count;
sample_tuples_count += chunk_size;
current_count = 0;
} else {
++current_count;
}
tuples_count += chunk_size;
}
private:
uint64_t Tick() const;
uint64_t tmp;
uint64_t time = 0;
uint64_t current_count = 0;
uint64_t next_sample = 0;
uint64_t sample_count = 0;
uint64_t sample_tuples_count = 0;
uint64_t tuples_count = 0;
};
}
#include <unordered_set>
namespace duckdb {
using std::unordered_set;
}
namespace duckdb {
struct CaseInsensitiveStringHashFunction {
uint64_t operator()(const string &str) const {
std::hash<string> hasher;
return hasher(StringUtil::Lower(str));
}
};
struct CaseInsensitiveStringEquality {
bool operator()(const string &a, const string &b) const {
return StringUtil::Lower(a) == StringUtil::Lower(b);
}
};
template <typename T>
using case_insensitive_map_t =
unordered_map<string, T, CaseInsensitiveStringHashFunction, CaseInsensitiveStringEquality>;
using case_insensitive_set_t = unordered_set<string, CaseInsensitiveStringHashFunction, CaseInsensitiveStringEquality>;
}
namespace duckdb {
using named_parameter_type_map_t = case_insensitive_map_t<LogicalType>;
using named_parameter_map_t = case_insensitive_map_t<Value>;
}
namespace duckdb {
enum ExternalDependenciesType { PYTHON_DEPENDENCY };
class ExternalDependency {
public:
explicit ExternalDependency(ExternalDependenciesType type_p) : type(type_p) {};
virtual ~ExternalDependency() {};
ExternalDependenciesType type;
};
}
namespace duckdb {
enum class ExpressionType : uint8_t {
INVALID = 0,
OPERATOR_CAST = 12,
OPERATOR_NOT = 13,
OPERATOR_IS_NULL = 14,
OPERATOR_IS_NOT_NULL = 15,
COMPARE_EQUAL = 25,
COMPARE_BOUNDARY_START = COMPARE_EQUAL,
COMPARE_NOTEQUAL = 26,
COMPARE_LESSTHAN = 27,
COMPARE_GREATERTHAN = 28,
COMPARE_LESSTHANOREQUALTO = 29,
COMPARE_GREATERTHANOREQUALTO = 30,
COMPARE_IN = 35,
COMPARE_NOT_IN = 36,
COMPARE_DISTINCT_FROM = 37,
COMPARE_BETWEEN = 38,
COMPARE_NOT_BETWEEN = 39,
COMPARE_NOT_DISTINCT_FROM = 40,
COMPARE_BOUNDARY_END = COMPARE_NOT_DISTINCT_FROM,
CONJUNCTION_AND = 50,
CONJUNCTION_OR = 51,
VALUE_CONSTANT = 75,
VALUE_PARAMETER = 76,
VALUE_TUPLE = 77,
VALUE_TUPLE_ADDRESS = 78,
VALUE_NULL = 79,
VALUE_VECTOR = 80,
VALUE_SCALAR = 81,
VALUE_DEFAULT = 82,
AGGREGATE = 100,
BOUND_AGGREGATE = 101,
GROUPING_FUNCTION = 102,
WINDOW_AGGREGATE = 110,
WINDOW_RANK = 120,
WINDOW_RANK_DENSE = 121,
WINDOW_NTILE = 122,
WINDOW_PERCENT_RANK = 123,
WINDOW_CUME_DIST = 124,
WINDOW_ROW_NUMBER = 125,
WINDOW_FIRST_VALUE = 130,
WINDOW_LAST_VALUE = 131,
WINDOW_LEAD = 132,
WINDOW_LAG = 133,
WINDOW_NTH_VALUE = 134,
FUNCTION = 140,
BOUND_FUNCTION = 141,
CASE_EXPR = 150,
OPERATOR_NULLIF = 151,
OPERATOR_COALESCE = 152,
ARRAY_EXTRACT = 153,
ARRAY_SLICE = 154,
STRUCT_EXTRACT = 155,
ARRAY_CONSTRUCTOR = 156,
ARROW = 157,
SUBQUERY = 175,
STAR = 200,
TABLE_STAR = 201,
PLACEHOLDER = 202,
COLUMN_REF = 203,
FUNCTION_REF = 204,
TABLE_REF = 205,
CAST = 225,
BOUND_REF = 227,
BOUND_COLUMN_REF = 228,
BOUND_UNNEST = 229,
COLLATE = 230,
LAMBDA = 231,
POSITIONAL_REFERENCE = 232,
BOUND_LAMBDA_REF = 233
};
enum class ExpressionClass : uint8_t {
INVALID = 0,
AGGREGATE = 1,
CASE = 2,
CAST = 3,
COLUMN_REF = 4,
COMPARISON = 5,
CONJUNCTION = 6,
CONSTANT = 7,
DEFAULT = 8,
FUNCTION = 9,
OPERATOR = 10,
STAR = 11,
SUBQUERY = 13,
WINDOW = 14,
PARAMETER = 15,
COLLATE = 16,
LAMBDA = 17,
POSITIONAL_REFERENCE = 18,
BETWEEN = 19,
BOUND_AGGREGATE = 25,
BOUND_CASE = 26,
BOUND_CAST = 27,
BOUND_COLUMN_REF = 28,
BOUND_COMPARISON = 29,
BOUND_CONJUNCTION = 30,
BOUND_CONSTANT = 31,
BOUND_DEFAULT = 32,
BOUND_FUNCTION = 33,
BOUND_OPERATOR = 34,
BOUND_PARAMETER = 35,
BOUND_REF = 36,
BOUND_SUBQUERY = 37,
BOUND_WINDOW = 38,
BOUND_BETWEEN = 39,
BOUND_UNNEST = 40,
BOUND_LAMBDA = 41,
BOUND_LAMBDA_REF = 42,
BOUND_EXPRESSION = 50
};
DUCKDB_API string ExpressionTypeToString(ExpressionType type);
string ExpressionTypeToOperator(ExpressionType type);
ExpressionType OperatorToExpressionType(const string &op);
ExpressionType NegateComparisionExpression(ExpressionType type);
ExpressionType FlipComparisionExpression(ExpressionType type);
DUCKDB_API string ExpressionClassToString(ExpressionClass type);
}
namespace duckdb {
class BaseExpression {
public:
BaseExpression(ExpressionType type, ExpressionClass expression_class)
: type(type), expression_class(expression_class) {
}
virtual ~BaseExpression() {
}
ExpressionType GetExpressionType() const {
return type;
}
ExpressionClass GetExpressionClass() const {
return expression_class;
}
ExpressionType type;
ExpressionClass expression_class;
string alias;
public:
virtual bool IsAggregate() const = 0;
virtual bool IsWindow() const = 0;
virtual bool HasSubquery() const = 0;
virtual bool IsScalar() const = 0;
virtual bool HasParameter() const = 0;
virtual string GetName() const;
virtual string ToString() const = 0;
void Print() const;
virtual hash_t Hash() const = 0;
virtual bool Equals(const BaseExpression *other) const;
static bool Equals(BaseExpression *left, BaseExpression *right) {
if (left == right) {
return true;
}
if (!left || !right) {
return false;
}
return left->Equals(right);
}
bool operator==(const BaseExpression &rhs) {
return this->Equals(&rhs);
}
virtual void Verify() const;
};
}
namespace duckdb {
class KeywordHelper {
public:
static bool IsKeyword(const string &text);
static bool RequiresQuotes(const string &text, bool allow_caps = false);
static string WriteOptionallyQuoted(const string &text, char quote = '"', bool allow_caps = false);
};
}
namespace duckdb {
struct QualifiedName {
string catalog;
string schema;
string name;
static QualifiedName Parse(const string &input) {
string catalog;
string schema;
string name;
idx_t idx = 0;
vector<string> entries;
string entry;
normal:
for (; idx < input.size(); idx++) {
if (input[idx] == '"') {
idx++;
goto quoted;
} else if (input[idx] == '.') {
goto separator;
}
entry += input[idx];
}
goto end;
separator:
entries.push_back(entry);
entry = "";
idx++;
goto normal;
quoted:
for (; idx < input.size(); idx++) {
if (input[idx] == '"') {
idx++;
goto normal;
}
entry += input[idx];
}
throw ParserException("Unterminated quote in qualified name!");
end:
if (entries.empty()) {
catalog = INVALID_CATALOG;
schema = INVALID_SCHEMA;
name = entry;
} else if (entries.size() == 1) {
catalog = INVALID_CATALOG;
schema = entries[0];
name = entry;
} else if (entries.size() == 2) {
catalog = entries[0];
schema = entries[1];
name = entry;
} else {
throw ParserException("Expected catalog.entry, schema.entry or entry: too many entries found");
}
return QualifiedName {catalog, schema, name};
}
};
struct QualifiedColumnName {
QualifiedColumnName() {
}
QualifiedColumnName(string table_p, string column_p) : table(std::move(table_p)), column(std::move(column_p)) {
}
string schema;
string table;
string column;
};
}
namespace duckdb {
class ParsedExpression;
class Expression;
class ExpressionUtil {
public:
static bool ListEquals(const vector<unique_ptr<ParsedExpression>> &a,
const vector<unique_ptr<ParsedExpression>> &b);
static bool ListEquals(const vector<unique_ptr<Expression>> &a, const vector<unique_ptr<Expression>> &b);
static bool SetEquals(const vector<unique_ptr<ParsedExpression>> &a, const vector<unique_ptr<ParsedExpression>> &b);
static bool SetEquals(const vector<unique_ptr<Expression>> &a, const vector<unique_ptr<Expression>> &b);
private:
template <class T>
static bool ExpressionListEquals(const vector<unique_ptr<T>> &a, const vector<unique_ptr<T>> &b);
template <class T>
static bool ExpressionSetEquals(const vector<unique_ptr<T>> &a, const vector<unique_ptr<T>> &b);
};
}
namespace duckdb {
class Serializer;
class Deserializer;
class FieldWriter;
class FieldReader;
class ParsedExpression : public BaseExpression {
public:
ParsedExpression(ExpressionType type, ExpressionClass expression_class) : BaseExpression(type, expression_class) {
}
idx_t query_location = DConstants::INVALID_INDEX;
public:
bool IsAggregate() const override;
bool IsWindow() const override;
bool HasSubquery() const override;
bool IsScalar() const override;
bool HasParameter() const override;
bool Equals(const BaseExpression *other) const override;
hash_t Hash() const override;
virtual unique_ptr<ParsedExpression> Copy() const = 0;
void Serialize(Serializer &serializer) const;
virtual void Serialize(FieldWriter &writer) const = 0;
static unique_ptr<ParsedExpression> Deserialize(Deserializer &source);
protected:
void CopyProperties(const ParsedExpression &other) {
type = other.type;
expression_class = other.expression_class;
alias = other.alias;
}
};
}
namespace duckdb {
enum class CompressionType : uint8_t {
COMPRESSION_AUTO = 0,
COMPRESSION_UNCOMPRESSED = 1,
COMPRESSION_CONSTANT = 2,
COMPRESSION_RLE = 3,
COMPRESSION_DICTIONARY = 4,
COMPRESSION_PFOR_DELTA = 5,
COMPRESSION_BITPACKING = 6,
COMPRESSION_FSST = 7,
COMPRESSION_CHIMP = 8,
COMPRESSION_PATAS = 9,
COMPRESSION_COUNT };
vector<string> ListCompressionTypes(void);
CompressionType CompressionTypeFromString(const string &str);
string CompressionTypeToString(CompressionType type);
}
namespace duckdb {
enum class TableColumnType : uint8_t { STANDARD = 0, GENERATED = 1 };
}
namespace duckdb {
struct RenameColumnInfo;
struct RenameTableInfo;
class ColumnDefinition;
class ColumnDefinition {
public:
DUCKDB_API ColumnDefinition(string name, LogicalType type);
DUCKDB_API ColumnDefinition(string name, LogicalType type, unique_ptr<ParsedExpression> expression,
TableColumnType category);
unique_ptr<ParsedExpression> default_value;
public:
const unique_ptr<ParsedExpression> &DefaultValue() const;
void SetDefaultValue(unique_ptr<ParsedExpression> default_value);
DUCKDB_API const LogicalType &Type() const;
LogicalType &TypeMutable();
void SetType(const LogicalType &type);
DUCKDB_API const string &Name() const;
void SetName(const string &name);
const duckdb::CompressionType &CompressionType() const;
void SetCompressionType(duckdb::CompressionType compression_type);
const storage_t &StorageOid() const;
void SetStorageOid(storage_t storage_oid);
LogicalIndex Logical() const;
PhysicalIndex Physical() const;
const column_t &Oid() const;
void SetOid(column_t oid);
const TableColumnType &Category() const;
bool Generated() const;
DUCKDB_API ColumnDefinition Copy() const;
DUCKDB_API void Serialize(Serializer &serializer) const;
DUCKDB_API static ColumnDefinition Deserialize(Deserializer &source);
ParsedExpression &GeneratedExpressionMutable();
const ParsedExpression &GeneratedExpression() const;
void SetGeneratedExpression(unique_ptr<ParsedExpression> expression);
void ChangeGeneratedExpressionType(const LogicalType &type);
void GetListOfDependencies(vector<string> &dependencies) const;
string GetName() const;
LogicalType GetType() const;
private:
string name;
LogicalType type;
duckdb::CompressionType compression_type = duckdb::CompressionType::COMPRESSION_AUTO;
storage_t storage_oid = DConstants::INVALID_INDEX;
idx_t oid = DConstants::INVALID_INDEX;
TableColumnType category = TableColumnType::STANDARD;
unique_ptr<ParsedExpression> generated_expression;
};
}
namespace duckdb {
class CatalogEntry;
class Catalog;
class ClientContext;
class Expression;
class ExpressionExecutor;
class Transaction;
class AggregateFunction;
class AggregateFunctionSet;
class CopyFunction;
class PragmaFunction;
class PragmaFunctionSet;
class ScalarFunctionSet;
class ScalarFunction;
class TableFunctionSet;
class TableFunction;
class SimpleFunction;
struct PragmaInfo;
enum class FunctionNullHandling : uint8_t { DEFAULT_NULL_HANDLING = 0, SPECIAL_HANDLING = 1 };
enum class FunctionSideEffects : uint8_t { NO_SIDE_EFFECTS = 0, HAS_SIDE_EFFECTS = 1 };
struct FunctionData {
DUCKDB_API virtual ~FunctionData();
DUCKDB_API virtual unique_ptr<FunctionData> Copy() const = 0;
DUCKDB_API virtual bool Equals(const FunctionData &other) const = 0;
DUCKDB_API static bool Equals(const FunctionData *left, const FunctionData *right);
};
struct TableFunctionData : public FunctionData {
vector<idx_t> column_ids;
DUCKDB_API virtual ~TableFunctionData();
DUCKDB_API unique_ptr<FunctionData> Copy() const override;
DUCKDB_API bool Equals(const FunctionData &other) const override;
};
struct PyTableFunctionData : public TableFunctionData {
unique_ptr<ExternalDependency> external_dependency;
};
struct FunctionParameters {
vector<Value> values;
named_parameter_map_t named_parameters;
};
class Function {
public:
DUCKDB_API explicit Function(string name);
DUCKDB_API virtual ~Function();
string name;
public:
DUCKDB_API static string CallToString(const string &name, const vector<LogicalType> &arguments);
DUCKDB_API static string CallToString(const string &name, const vector<LogicalType> &arguments,
const LogicalType &return_type);
DUCKDB_API static string CallToString(const string &name, const vector<LogicalType> &arguments,
const named_parameter_type_map_t &named_parameters);
DUCKDB_API static void EraseArgument(SimpleFunction &bound_function, vector<unique_ptr<Expression>> &arguments,
idx_t argument_index);
};
class SimpleFunction : public Function {
public:
DUCKDB_API SimpleFunction(string name, vector<LogicalType> arguments,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID));
DUCKDB_API ~SimpleFunction() override;
vector<LogicalType> arguments;
vector<LogicalType> original_arguments;
LogicalType varargs;
public:
DUCKDB_API virtual string ToString();
DUCKDB_API bool HasVarArgs() const;
};
class SimpleNamedParameterFunction : public SimpleFunction {
public:
DUCKDB_API SimpleNamedParameterFunction(string name, vector<LogicalType> arguments,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID));
DUCKDB_API ~SimpleNamedParameterFunction() override;
named_parameter_type_map_t named_parameters;
public:
DUCKDB_API string ToString() override;
DUCKDB_API bool HasNamedParameters();
};
class BaseScalarFunction : public SimpleFunction {
public:
DUCKDB_API BaseScalarFunction(string name, vector<LogicalType> arguments, LogicalType return_type,
FunctionSideEffects side_effects,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID),
FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING);
DUCKDB_API ~BaseScalarFunction() override;
LogicalType return_type;
FunctionSideEffects side_effects;
FunctionNullHandling null_handling;
public:
DUCKDB_API hash_t Hash() const;
DUCKDB_API string ToString() override;
};
}
namespace duckdb {
class Expression;
class ExpressionExecutor;
struct ExpressionExecutorState;
struct FunctionLocalState;
struct ExpressionState {
ExpressionState(const Expression &expr, ExpressionExecutorState &root);
virtual ~ExpressionState() {
}
const Expression &expr;
ExpressionExecutorState &root;
vector<unique_ptr<ExpressionState>> child_states;
vector<LogicalType> types;
DataChunk intermediate_chunk;
string name;
CycleCounter profiler;
public:
void AddChild(Expression *expr);
void Finalize();
Allocator &GetAllocator();
bool HasContext();
DUCKDB_API ClientContext &GetContext();
void Verify(ExpressionExecutorState &root);
};
struct ExecuteFunctionState : public ExpressionState {
ExecuteFunctionState(const Expression &expr, ExpressionExecutorState &root);
~ExecuteFunctionState();
unique_ptr<FunctionLocalState> local_state;
public:
DUCKDB_API static FunctionLocalState *GetFunctionState(ExpressionState &state) {
return ((ExecuteFunctionState &)state).local_state.get();
}
};
struct ExpressionExecutorState {
explicit ExpressionExecutorState(const string &name);
unique_ptr<ExpressionState> root_state;
ExpressionExecutor *executor = nullptr;
CycleCounter profiler;
string name;
void Verify();
};
}
namespace duckdb {
template <class T>
PhysicalType GetTypeId() {
if (std::is_same<T, bool>()) {
return PhysicalType::BOOL;
} else if (std::is_same<T, int8_t>()) {
return PhysicalType::INT8;
} else if (std::is_same<T, int16_t>()) {
return PhysicalType::INT16;
} else if (std::is_same<T, int32_t>()) {
return PhysicalType::INT32;
} else if (std::is_same<T, int64_t>()) {
return PhysicalType::INT64;
} else if (std::is_same<T, uint8_t>()) {
return PhysicalType::UINT8;
} else if (std::is_same<T, uint16_t>()) {
return PhysicalType::UINT16;
} else if (std::is_same<T, uint32_t>()) {
return PhysicalType::UINT32;
} else if (std::is_same<T, uint64_t>()) {
return PhysicalType::UINT64;
} else if (std::is_same<T, hugeint_t>()) {
return PhysicalType::INT128;
} else if (std::is_same<T, date_t>()) {
return PhysicalType::INT32;
} else if (std::is_same<T, dtime_t>()) {
return PhysicalType::INT64;
} else if (std::is_same<T, timestamp_t>()) {
return PhysicalType::INT64;
} else if (std::is_same<T, float>()) {
return PhysicalType::FLOAT;
} else if (std::is_same<T, double>()) {
return PhysicalType::DOUBLE;
} else if (std::is_same<T, const char *>() || std::is_same<T, char *>() || std::is_same<T, string_t>()) {
return PhysicalType::VARCHAR;
} else if (std::is_same<T, interval_t>()) {
return PhysicalType::INTERVAL;
} else {
return PhysicalType::INVALID;
}
}
template <class T>
bool TypeIsNumber() {
return std::is_integral<T>() || std::is_floating_point<T>() || std::is_same<T, hugeint_t>();
}
template <class T>
bool IsValidType() {
return GetTypeId<T>() != PhysicalType::INVALID;
}
template <class T>
bool IsIntegerType() {
return TypeIsIntegral(GetTypeId<T>());
}
}
namespace duckdb {
class Hugeint {
public:
static string ToString(hugeint_t input);
template <class T>
DUCKDB_API static bool TryCast(hugeint_t input, T &result);
template <class T>
static T Cast(hugeint_t input) {
T result = 0;
TryCast(input, result);
return result;
}
template <class T>
static bool TryConvert(T value, hugeint_t &result);
template <class T>
static hugeint_t Convert(T value) {
hugeint_t result;
if (!TryConvert(value, result)) { throw ValueOutOfRangeException(double(value), GetTypeId<T>(), GetTypeId<hugeint_t>());
} return result;
}
static void NegateInPlace(hugeint_t &input) {
if (input.upper == NumericLimits<int64_t>::Minimum() && input.lower == 0) {
throw OutOfRangeException("HUGEINT is out of range");
}
input.lower = NumericLimits<uint64_t>::Maximum() - input.lower + 1;
input.upper = -1 - input.upper + (input.lower == 0);
}
static hugeint_t Negate(hugeint_t input) {
NegateInPlace(input);
return input;
}
static bool TryMultiply(hugeint_t lhs, hugeint_t rhs, hugeint_t &result);
static hugeint_t Add(hugeint_t lhs, hugeint_t rhs);
static hugeint_t Subtract(hugeint_t lhs, hugeint_t rhs);
static hugeint_t Multiply(hugeint_t lhs, hugeint_t rhs);
static hugeint_t Divide(hugeint_t lhs, hugeint_t rhs);
static hugeint_t Modulo(hugeint_t lhs, hugeint_t rhs);
static hugeint_t DivMod(hugeint_t lhs, hugeint_t rhs, hugeint_t &remainder);
static hugeint_t DivModPositive(hugeint_t lhs, uint64_t rhs, uint64_t &remainder);
static bool AddInPlace(hugeint_t &lhs, hugeint_t rhs);
static bool SubtractInPlace(hugeint_t &lhs, hugeint_t rhs);
static bool Equals(hugeint_t lhs, hugeint_t rhs) {
int lower_equals = lhs.lower == rhs.lower;
int upper_equals = lhs.upper == rhs.upper;
return lower_equals & upper_equals;
}
static bool NotEquals(hugeint_t lhs, hugeint_t rhs) {
int lower_not_equals = lhs.lower != rhs.lower;
int upper_not_equals = lhs.upper != rhs.upper;
return lower_not_equals | upper_not_equals;
}
static bool GreaterThan(hugeint_t lhs, hugeint_t rhs) {
int upper_bigger = lhs.upper > rhs.upper;
int upper_equal = lhs.upper == rhs.upper;
int lower_bigger = lhs.lower > rhs.lower;
return upper_bigger | (upper_equal & lower_bigger);
}
static bool GreaterThanEquals(hugeint_t lhs, hugeint_t rhs) {
int upper_bigger = lhs.upper > rhs.upper;
int upper_equal = lhs.upper == rhs.upper;
int lower_bigger_equals = lhs.lower >= rhs.lower;
return upper_bigger | (upper_equal & lower_bigger_equals);
}
static bool LessThan(hugeint_t lhs, hugeint_t rhs) {
int upper_smaller = lhs.upper < rhs.upper;
int upper_equal = lhs.upper == rhs.upper;
int lower_smaller = lhs.lower < rhs.lower;
return upper_smaller | (upper_equal & lower_smaller);
}
static bool LessThanEquals(hugeint_t lhs, hugeint_t rhs) {
int upper_smaller = lhs.upper < rhs.upper;
int upper_equal = lhs.upper == rhs.upper;
int lower_smaller_equals = lhs.lower <= rhs.lower;
return upper_smaller | (upper_equal & lower_smaller_equals);
}
static const hugeint_t POWERS_OF_TEN[40];
};
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, int8_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, int16_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, int32_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, int64_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, uint8_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, uint16_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, uint32_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, uint64_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, hugeint_t &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, float &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, double &result);
template <>
DUCKDB_API bool Hugeint::TryCast(hugeint_t input, long double &result);
template <>
bool Hugeint::TryConvert(int8_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(int16_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(int32_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(int64_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(uint8_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(uint16_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(uint32_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(uint64_t value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(float value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(double value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(long double value, hugeint_t &result);
template <>
bool Hugeint::TryConvert(const char *value, hugeint_t &result);
}
#include <cstring>
namespace duckdb {
struct Equals {
template <class T>
DUCKDB_API static inline bool Operation(T left, T right) {
return left == right;
}
};
struct NotEquals {
template <class T>
DUCKDB_API static inline bool Operation(T left, T right) {
return !Equals::Operation(left, right);
}
};
struct GreaterThan {
template <class T>
DUCKDB_API static inline bool Operation(T left, T right) {
return left > right;
}
};
struct GreaterThanEquals {
template <class T>
DUCKDB_API static inline bool Operation(T left, T right) {
return left >= right;
}
};
struct LessThan {
template <class T>
DUCKDB_API static inline bool Operation(T left, T right) {
return GreaterThan::Operation(right, left);
}
};
struct LessThanEquals {
template <class T>
DUCKDB_API static inline bool Operation(T left, T right) {
return GreaterThanEquals::Operation(right, left);
}
};
template <>
DUCKDB_API bool Equals::Operation(float left, float right);
template <>
DUCKDB_API bool Equals::Operation(double left, double right);
template <>
DUCKDB_API bool GreaterThan::Operation(float left, float right);
template <>
DUCKDB_API bool GreaterThan::Operation(double left, double right);
template <>
DUCKDB_API bool GreaterThanEquals::Operation(float left, float right);
template <>
DUCKDB_API bool GreaterThanEquals::Operation(double left, double right);
struct DistinctFrom {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return (left_null != right_null) || (!left_null && !right_null && NotEquals::Operation(left, right));
}
};
struct NotDistinctFrom {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return (left_null && right_null) || (!left_null && !right_null && Equals::Operation(left, right));
}
};
struct DistinctGreaterThan {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return GreaterThan::Operation(left_null, right_null) ||
(!left_null && !right_null && GreaterThan::Operation(left, right));
}
};
struct DistinctGreaterThanNullsFirst {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return GreaterThan::Operation(right_null, left_null) ||
(!left_null && !right_null && GreaterThan::Operation(left, right));
}
};
struct DistinctGreaterThanEquals {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return left_null || (!left_null && !right_null && GreaterThanEquals::Operation(left, right));
}
};
struct DistinctLessThan {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return LessThan::Operation(left_null, right_null) ||
(!left_null && !right_null && LessThan::Operation(left, right));
}
};
struct DistinctLessThanNullsFirst {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return LessThan::Operation(right_null, left_null) ||
(!left_null && !right_null && LessThan::Operation(left, right));
}
};
struct DistinctLessThanEquals {
template <class T>
static inline bool Operation(T left, T right, bool left_null, bool right_null) {
return right_null || (!left_null && !right_null && LessThanEquals::Operation(left, right));
}
};
template <>
inline bool GreaterThan::Operation(bool left, bool right) {
return !right && left;
}
template <>
inline bool LessThan::Operation(bool left, bool right) {
return !left && right;
}
struct StringComparisonOperators {
template <bool INVERSE>
static inline bool EqualsOrNot(const string_t a, const string_t b) {
if (a.IsInlined()) {
if (memcmp(&a, &b, sizeof(string_t)) == 0) {
return INVERSE ? false : true;
}
} else {
if (memcmp(&a, &b, string_t::HEADER_SIZE) == 0) {
if (memcmp(a.value.pointer.ptr, b.value.pointer.ptr, a.GetSize()) == 0) {
return INVERSE ? false : true;
}
}
}
return INVERSE ? true : false;
}
};
template <>
inline bool Equals::Operation(string_t left, string_t right) {
return StringComparisonOperators::EqualsOrNot<false>(left, right);
}
template <>
inline bool NotEquals::Operation(string_t left, string_t right) {
return StringComparisonOperators::EqualsOrNot<true>(left, right);
}
template <>
inline bool NotDistinctFrom::Operation(string_t left, string_t right, bool left_null, bool right_null) {
return (left_null && right_null) ||
(!left_null && !right_null && StringComparisonOperators::EqualsOrNot<false>(left, right));
}
template <>
inline bool DistinctFrom::Operation(string_t left, string_t right, bool left_null, bool right_null) {
return (left_null != right_null) ||
(!left_null && !right_null && StringComparisonOperators::EqualsOrNot<true>(left, right));
}
template <class OP>
static bool templated_string_compare_op(string_t left, string_t right) {
auto memcmp_res =
memcmp(left.GetDataUnsafe(), right.GetDataUnsafe(), MinValue<idx_t>(left.GetSize(), right.GetSize()));
auto final_res = memcmp_res == 0 ? OP::Operation(left.GetSize(), right.GetSize()) : OP::Operation(memcmp_res, 0);
return final_res;
}
template <>
inline bool GreaterThan::Operation(string_t left, string_t right) {
return templated_string_compare_op<GreaterThan>(left, right);
}
template <>
inline bool GreaterThanEquals::Operation(string_t left, string_t right) {
return templated_string_compare_op<GreaterThanEquals>(left, right);
}
template <>
inline bool LessThan::Operation(string_t left, string_t right) {
return templated_string_compare_op<LessThan>(left, right);
}
template <>
inline bool LessThanEquals::Operation(string_t left, string_t right) {
return templated_string_compare_op<LessThanEquals>(left, right);
}
template <>
inline bool Equals::Operation(interval_t left, interval_t right) {
return Interval::Equals(left, right);
}
template <>
inline bool NotEquals::Operation(interval_t left, interval_t right) {
return !Equals::Operation(left, right);
}
template <>
inline bool GreaterThan::Operation(interval_t left, interval_t right) {
return Interval::GreaterThan(left, right);
}
template <>
inline bool GreaterThanEquals::Operation(interval_t left, interval_t right) {
return Interval::GreaterThanEquals(left, right);
}
template <>
inline bool LessThan::Operation(interval_t left, interval_t right) {
return GreaterThan::Operation(right, left);
}
template <>
inline bool LessThanEquals::Operation(interval_t left, interval_t right) {
return GreaterThanEquals::Operation(right, left);
}
template <>
inline bool NotDistinctFrom::Operation(interval_t left, interval_t right, bool left_null, bool right_null) {
return (left_null && right_null) || (!left_null && !right_null && Interval::Equals(left, right));
}
template <>
inline bool DistinctFrom::Operation(interval_t left, interval_t right, bool left_null, bool right_null) {
return (left_null != right_null) || (!left_null && !right_null && !Equals::Operation(left, right));
}
inline bool operator<(const interval_t &lhs, const interval_t &rhs) {
return LessThan::Operation(lhs, rhs);
}
template <>
inline bool Equals::Operation(hugeint_t left, hugeint_t right) {
return Hugeint::Equals(left, right);
}
template <>
inline bool NotEquals::Operation(hugeint_t left, hugeint_t right) {
return Hugeint::NotEquals(left, right);
}
template <>
inline bool GreaterThan::Operation(hugeint_t left, hugeint_t right) {
return Hugeint::GreaterThan(left, right);
}
template <>
inline bool GreaterThanEquals::Operation(hugeint_t left, hugeint_t right) {
return Hugeint::GreaterThanEquals(left, right);
}
template <>
inline bool LessThan::Operation(hugeint_t left, hugeint_t right) {
return Hugeint::LessThan(left, right);
}
template <>
inline bool LessThanEquals::Operation(hugeint_t left, hugeint_t right) {
return Hugeint::LessThanEquals(left, right);
}
}
namespace duckdb {
struct SelectionVector;
class Serializer;
class Deserializer;
class FieldWriter;
class FieldReader;
class Vector;
class ValidityStatistics;
class DistinctStatistics;
struct UnifiedVectorFormat;
enum StatisticsType { LOCAL_STATS = 0, GLOBAL_STATS = 1 };
class BaseStatistics {
public:
BaseStatistics(LogicalType type, StatisticsType stats_type);
virtual ~BaseStatistics();
LogicalType type;
unique_ptr<BaseStatistics> validity_stats;
unique_ptr<BaseStatistics> distinct_stats;
StatisticsType stats_type;
public:
static unique_ptr<BaseStatistics> CreateEmpty(LogicalType type, StatisticsType stats_type);
DUCKDB_API bool CanHaveNull() const;
DUCKDB_API bool CanHaveNoNull() const;
void UpdateDistinctStatistics(Vector &v, idx_t count);
virtual bool IsConstant() const {
return false;
}
virtual void Merge(const BaseStatistics &other);
virtual unique_ptr<BaseStatistics> Copy() const;
void CopyBase(const BaseStatistics &orig);
virtual void Serialize(Serializer &serializer) const;
virtual void Serialize(FieldWriter &writer) const;
virtual idx_t GetDistinctCount();
static unique_ptr<BaseStatistics> Deserialize(Deserializer &source, LogicalType type);
virtual void Verify(Vector &vector, const SelectionVector &sel, idx_t count) const;
void Verify(Vector &vector, idx_t count) const;
virtual string ToString() const;
protected:
void InitializeBase();
};
}
namespace duckdb {
struct FunctionLocalState {
DUCKDB_API virtual ~FunctionLocalState();
};
class Binder;
class BoundFunctionExpression;
class DependencyList;
class ScalarFunctionCatalogEntry;
struct FunctionStatisticsInput {
FunctionStatisticsInput(BoundFunctionExpression &expr_p, FunctionData *bind_data_p,
vector<unique_ptr<BaseStatistics>> &child_stats_p, unique_ptr<Expression> *expr_ptr_p)
: expr(expr_p), bind_data(bind_data_p), child_stats(child_stats_p), expr_ptr(expr_ptr_p) {
}
BoundFunctionExpression &expr;
FunctionData *bind_data;
vector<unique_ptr<BaseStatistics>> &child_stats;
unique_ptr<Expression> *expr_ptr;
};
typedef std::function<void(DataChunk &, ExpressionState &, Vector &)> scalar_function_t;
typedef unique_ptr<FunctionData> (*bind_scalar_function_t)(ClientContext &context, ScalarFunction &bound_function,
vector<unique_ptr<Expression>> &arguments);
typedef unique_ptr<FunctionLocalState> (*init_local_state_t)(ExpressionState &state,
const BoundFunctionExpression &expr,
FunctionData *bind_data);
typedef unique_ptr<BaseStatistics> (*function_statistics_t)(ClientContext &context, FunctionStatisticsInput &input);
typedef void (*dependency_function_t)(BoundFunctionExpression &expr, DependencyList &dependencies);
typedef void (*function_serialize_t)(FieldWriter &writer, const FunctionData *bind_data,
const ScalarFunction &function);
typedef unique_ptr<FunctionData> (*function_deserialize_t)(ClientContext &context, FieldReader &reader,
ScalarFunction &function);
class ScalarFunction : public BaseScalarFunction {
public:
DUCKDB_API ScalarFunction(string name, vector<LogicalType> arguments, LogicalType return_type,
scalar_function_t function, bind_scalar_function_t bind = nullptr,
dependency_function_t dependency = nullptr, function_statistics_t statistics = nullptr,
init_local_state_t init_local_state = nullptr,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID),
FunctionSideEffects side_effects = FunctionSideEffects::NO_SIDE_EFFECTS,
FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING);
DUCKDB_API ScalarFunction(vector<LogicalType> arguments, LogicalType return_type, scalar_function_t function,
bind_scalar_function_t bind = nullptr, dependency_function_t dependency = nullptr,
function_statistics_t statistics = nullptr, init_local_state_t init_local_state = nullptr,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID),
FunctionSideEffects side_effects = FunctionSideEffects::NO_SIDE_EFFECTS,
FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING);
scalar_function_t function;
bind_scalar_function_t bind;
init_local_state_t init_local_state;
dependency_function_t dependency;
function_statistics_t statistics;
function_serialize_t serialize;
function_deserialize_t deserialize;
DUCKDB_API bool operator==(const ScalarFunction &rhs) const;
DUCKDB_API bool operator!=(const ScalarFunction &rhs) const;
DUCKDB_API bool Equal(const ScalarFunction &rhs) const;
private:
bool CompareScalarFunctionT(const scalar_function_t &other) const;
public:
DUCKDB_API static void NopFunction(DataChunk &input, ExpressionState &state, Vector &result);
template <class TA, class TR, class OP>
static void UnaryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
D_ASSERT(input.ColumnCount() >= 1);
UnaryExecutor::Execute<TA, TR, OP>(input.data[0], result, input.size());
}
template <class TA, class TB, class TR, class OP>
static void BinaryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
D_ASSERT(input.ColumnCount() == 2);
BinaryExecutor::ExecuteStandard<TA, TB, TR, OP>(input.data[0], input.data[1], result, input.size());
}
template <class TA, class TB, class TC, class TR, class OP>
static void TernaryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
D_ASSERT(input.ColumnCount() == 3);
TernaryExecutor::ExecuteStandard<TA, TB, TC, TR, OP>(input.data[0], input.data[1], input.data[2], result,
input.size());
}
public:
template <class OP>
static scalar_function_t GetScalarUnaryFunction(LogicalType type) {
scalar_function_t function;
switch (type.id()) {
case LogicalTypeId::TINYINT:
function = &ScalarFunction::UnaryFunction<int8_t, int8_t, OP>;
break;
case LogicalTypeId::SMALLINT:
function = &ScalarFunction::UnaryFunction<int16_t, int16_t, OP>;
break;
case LogicalTypeId::INTEGER:
function = &ScalarFunction::UnaryFunction<int32_t, int32_t, OP>;
break;
case LogicalTypeId::BIGINT:
function = &ScalarFunction::UnaryFunction<int64_t, int64_t, OP>;
break;
case LogicalTypeId::UTINYINT:
function = &ScalarFunction::UnaryFunction<uint8_t, uint8_t, OP>;
break;
case LogicalTypeId::USMALLINT:
function = &ScalarFunction::UnaryFunction<uint16_t, uint16_t, OP>;
break;
case LogicalTypeId::UINTEGER:
function = &ScalarFunction::UnaryFunction<uint32_t, uint32_t, OP>;
break;
case LogicalTypeId::UBIGINT:
function = &ScalarFunction::UnaryFunction<uint64_t, uint64_t, OP>;
break;
case LogicalTypeId::HUGEINT:
function = &ScalarFunction::UnaryFunction<hugeint_t, hugeint_t, OP>;
break;
case LogicalTypeId::FLOAT:
function = &ScalarFunction::UnaryFunction<float, float, OP>;
break;
case LogicalTypeId::DOUBLE:
function = &ScalarFunction::UnaryFunction<double, double, OP>;
break;
default:
throw InternalException("Unimplemented type for GetScalarUnaryFunction");
}
return function;
}
template <class TR, class OP>
static scalar_function_t GetScalarUnaryFunctionFixedReturn(LogicalType type) {
scalar_function_t function;
switch (type.id()) {
case LogicalTypeId::TINYINT:
function = &ScalarFunction::UnaryFunction<int8_t, TR, OP>;
break;
case LogicalTypeId::SMALLINT:
function = &ScalarFunction::UnaryFunction<int16_t, TR, OP>;
break;
case LogicalTypeId::INTEGER:
function = &ScalarFunction::UnaryFunction<int32_t, TR, OP>;
break;
case LogicalTypeId::BIGINT:
function = &ScalarFunction::UnaryFunction<int64_t, TR, OP>;
break;
case LogicalTypeId::UTINYINT:
function = &ScalarFunction::UnaryFunction<uint8_t, TR, OP>;
break;
case LogicalTypeId::USMALLINT:
function = &ScalarFunction::UnaryFunction<uint16_t, TR, OP>;
break;
case LogicalTypeId::UINTEGER:
function = &ScalarFunction::UnaryFunction<uint32_t, TR, OP>;
break;
case LogicalTypeId::UBIGINT:
function = &ScalarFunction::UnaryFunction<uint64_t, TR, OP>;
break;
case LogicalTypeId::HUGEINT:
function = &ScalarFunction::UnaryFunction<hugeint_t, TR, OP>;
break;
case LogicalTypeId::FLOAT:
function = &ScalarFunction::UnaryFunction<float, TR, OP>;
break;
case LogicalTypeId::DOUBLE:
function = &ScalarFunction::UnaryFunction<double, TR, OP>;
break;
default:
throw InternalException("Unimplemented type for GetScalarUnaryFunctionFixedReturn");
}
return function;
}
};
}
namespace duckdb {
class NodeStatistics {
public:
NodeStatistics() : has_estimated_cardinality(false), has_max_cardinality(false) {
}
explicit NodeStatistics(idx_t estimated_cardinality)
: has_estimated_cardinality(true), estimated_cardinality(estimated_cardinality), has_max_cardinality(false) {
}
NodeStatistics(idx_t estimated_cardinality, idx_t max_cardinality)
: has_estimated_cardinality(true), estimated_cardinality(estimated_cardinality), has_max_cardinality(true),
max_cardinality(max_cardinality) {
}
bool has_estimated_cardinality;
idx_t estimated_cardinality;
bool has_max_cardinality;
idx_t max_cardinality;
};
}
namespace duckdb {
enum class OrderType : uint8_t { INVALID = 0, ORDER_DEFAULT = 1, ASCENDING = 2, DESCENDING = 3 };
enum class OrderByNullType : uint8_t { INVALID = 0, ORDER_DEFAULT = 1, NULLS_FIRST = 2, NULLS_LAST = 3 };
}
namespace duckdb {
class FieldWriter;
class FieldReader;
enum ResultModifierType : uint8_t {
LIMIT_MODIFIER = 1,
ORDER_MODIFIER = 2,
DISTINCT_MODIFIER = 3,
LIMIT_PERCENT_MODIFIER = 4
};
class ResultModifier {
public:
explicit ResultModifier(ResultModifierType type) : type(type) {
}
virtual ~ResultModifier() {
}
ResultModifierType type;
public:
virtual bool Equals(const ResultModifier *other) const;
virtual unique_ptr<ResultModifier> Copy() const = 0;
void Serialize(Serializer &serializer) const;
virtual void Serialize(FieldWriter &writer) const = 0;
static unique_ptr<ResultModifier> Deserialize(Deserializer &source);
};
struct OrderByNode {
OrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<ParsedExpression> expression)
: type(type), null_order(null_order), expression(std::move(expression)) {
}
OrderType type;
OrderByNullType null_order;
unique_ptr<ParsedExpression> expression;
public:
void Serialize(Serializer &serializer) const;
string ToString() const;
static OrderByNode Deserialize(Deserializer &source);
};
class LimitModifier : public ResultModifier {
public:
LimitModifier() : ResultModifier(ResultModifierType::LIMIT_MODIFIER) {
}
unique_ptr<ParsedExpression> limit;
unique_ptr<ParsedExpression> offset;
public:
bool Equals(const ResultModifier *other) const override;
unique_ptr<ResultModifier> Copy() const override;
void Serialize(FieldWriter &writer) const override;
static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
};
class OrderModifier : public ResultModifier {
public:
OrderModifier() : ResultModifier(ResultModifierType::ORDER_MODIFIER) {
}
vector<OrderByNode> orders;
public:
bool Equals(const ResultModifier *other) const override;
unique_ptr<ResultModifier> Copy() const override;
void Serialize(FieldWriter &writer) const override;
static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
};
class DistinctModifier : public ResultModifier {
public:
DistinctModifier() : ResultModifier(ResultModifierType::DISTINCT_MODIFIER) {
}
vector<unique_ptr<ParsedExpression>> distinct_on_targets;
public:
bool Equals(const ResultModifier *other) const override;
unique_ptr<ResultModifier> Copy() const override;
void Serialize(FieldWriter &writer) const override;
static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
};
class LimitPercentModifier : public ResultModifier {
public:
LimitPercentModifier() : ResultModifier(ResultModifierType::LIMIT_PERCENT_MODIFIER) {
}
unique_ptr<ParsedExpression> limit;
unique_ptr<ParsedExpression> offset;
public:
bool Equals(const ResultModifier *other) const override;
unique_ptr<ResultModifier> Copy() const override;
void Serialize(FieldWriter &writer) const override;
static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
};
}
namespace duckdb {
class LogicalOperator;
struct LogicalType;
struct BoundStatement {
unique_ptr<LogicalOperator> plan;
vector<LogicalType> types;
vector<string> names;
};
}
namespace duckdb {
enum class LogicalOperatorType : uint8_t {
LOGICAL_INVALID = 0,
LOGICAL_PROJECTION = 1,
LOGICAL_FILTER = 2,
LOGICAL_AGGREGATE_AND_GROUP_BY = 3,
LOGICAL_WINDOW = 4,
LOGICAL_UNNEST = 5,
LOGICAL_LIMIT = 6,
LOGICAL_ORDER_BY = 7,
LOGICAL_TOP_N = 8,
LOGICAL_COPY_TO_FILE = 10,
LOGICAL_DISTINCT = 11,
LOGICAL_SAMPLE = 12,
LOGICAL_LIMIT_PERCENT = 13,
LOGICAL_GET = 25,
LOGICAL_CHUNK_GET = 26,
LOGICAL_DELIM_GET = 27,
LOGICAL_EXPRESSION_GET = 28,
LOGICAL_DUMMY_SCAN = 29,
LOGICAL_EMPTY_RESULT = 30,
LOGICAL_CTE_REF = 31,
LOGICAL_JOIN = 50,
LOGICAL_DELIM_JOIN = 51,
LOGICAL_COMPARISON_JOIN = 52,
LOGICAL_ANY_JOIN = 53,
LOGICAL_CROSS_PRODUCT = 54,
LOGICAL_POSITIONAL_JOIN = 55,
LOGICAL_UNION = 75,
LOGICAL_EXCEPT = 76,
LOGICAL_INTERSECT = 77,
LOGICAL_RECURSIVE_CTE = 78,
LOGICAL_INSERT = 100,
LOGICAL_DELETE = 101,
LOGICAL_UPDATE = 102,
LOGICAL_ALTER = 125,
LOGICAL_CREATE_TABLE = 126,
LOGICAL_CREATE_INDEX = 127,
LOGICAL_CREATE_SEQUENCE = 128,
LOGICAL_CREATE_VIEW = 129,
LOGICAL_CREATE_SCHEMA = 130,
LOGICAL_CREATE_MACRO = 131,
LOGICAL_DROP = 132,
LOGICAL_PRAGMA = 133,
LOGICAL_TRANSACTION = 134,
LOGICAL_CREATE_TYPE = 135,
LOGICAL_ATTACH = 136,
LOGICAL_DETACH = 137,
LOGICAL_EXPLAIN = 150,
LOGICAL_SHOW = 160,
LOGICAL_PREPARE = 175,
LOGICAL_EXECUTE = 176,
LOGICAL_EXPORT = 177,
LOGICAL_VACUUM = 178,
LOGICAL_SET = 179,
LOGICAL_LOAD = 180,
LOGICAL_RESET = 181,
LOGICAL_EXTENSION_OPERATOR = 255
};
DUCKDB_API string LogicalOperatorToString(LogicalOperatorType type);
}
namespace duckdb {
struct BoundParameterData;
using bound_parameter_map_t = unordered_map<idx_t, shared_ptr<BoundParameterData>>;
}
namespace duckdb {
class ClientContext;
class LogicalOperator;
struct BoundParameterData;
struct PlanDeserializationState {
PlanDeserializationState(ClientContext &context);
~PlanDeserializationState();
ClientContext &context;
bound_parameter_map_t parameter_data;
};
struct LogicalDeserializationState {
LogicalDeserializationState(PlanDeserializationState &gstate, LogicalOperatorType type,
vector<unique_ptr<LogicalOperator>> &children);
PlanDeserializationState &gstate;
LogicalOperatorType type;
vector<unique_ptr<LogicalOperator>> &children;
};
struct ExpressionDeserializationState {
ExpressionDeserializationState(PlanDeserializationState &gstate, ExpressionType type);
PlanDeserializationState &gstate;
ExpressionType type;
};
}
namespace duckdb {
class BaseStatistics;
class FieldWriter;
class FieldReader;
class ClientContext;
class Expression : public BaseExpression {
public:
Expression(ExpressionType type, ExpressionClass expression_class, LogicalType return_type);
~Expression() override;
LogicalType return_type;
unique_ptr<BaseStatistics> verification_stats;
public:
bool IsAggregate() const override;
bool IsWindow() const override;
bool HasSubquery() const override;
bool IsScalar() const override;
bool HasParameter() const override;
virtual bool HasSideEffects() const;
virtual bool PropagatesNullValues() const;
virtual bool IsFoldable() const;
hash_t Hash() const override;
bool Equals(const BaseExpression *other) const override {
if (!BaseExpression::Equals(other)) {
return false;
}
return return_type == ((Expression *)other)->return_type;
}
static bool Equals(Expression *left, Expression *right) {
return BaseExpression::Equals((BaseExpression *)left, (BaseExpression *)right);
}
virtual unique_ptr<Expression> Copy() = 0;
void Serialize(Serializer &serializer) const;
virtual void Serialize(FieldWriter &writer) const = 0;
static unique_ptr<Expression> Deserialize(Deserializer &source, PlanDeserializationState &state);
protected:
void CopyProperties(Expression &other) {
type = other.type;
expression_class = other.expression_class;
alias = other.alias;
return_type = other.return_type;
}
};
}
namespace duckdb {
class BoundResultModifier {
public:
explicit BoundResultModifier(ResultModifierType type);
virtual ~BoundResultModifier();
ResultModifierType type;
};
struct BoundOrderByNode {
public:
BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<Expression> expression);
BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<Expression> expression,
unique_ptr<BaseStatistics> stats);
OrderType type;
OrderByNullType null_order;
unique_ptr<Expression> expression;
unique_ptr<BaseStatistics> stats;
public:
BoundOrderByNode Copy() const;
bool Equals(const BoundOrderByNode &other) const;
string ToString() const;
void Serialize(Serializer &serializer) const;
static BoundOrderByNode Deserialize(Deserializer &source, PlanDeserializationState &state);
};
class BoundLimitModifier : public BoundResultModifier {
public:
BoundLimitModifier();
int64_t limit_val = NumericLimits<int64_t>::Maximum();
int64_t offset_val = 0;
unique_ptr<Expression> limit;
unique_ptr<Expression> offset;
};
class BoundOrderModifier : public BoundResultModifier {
public:
BoundOrderModifier();
vector<BoundOrderByNode> orders;
};
class BoundDistinctModifier : public BoundResultModifier {
public:
BoundDistinctModifier();
vector<unique_ptr<Expression>> target_distincts;
};
class BoundLimitPercentModifier : public BoundResultModifier {
public:
BoundLimitPercentModifier();
double limit_percent = 100.0;
int64_t offset_val = 0;
unique_ptr<Expression> limit;
unique_ptr<Expression> offset;
};
}
namespace duckdb {
struct AggregateInputData;
typedef std::pair<idx_t, idx_t> FrameBounds;
class AggregateExecutor {
private:
template <class STATE_TYPE, class OP>
static inline void NullaryFlatLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data,
idx_t count) {
for (idx_t i = 0; i < count; i++) {
OP::template Operation<STATE_TYPE, OP>(states[i], aggr_input_data, i);
}
}
template <class STATE_TYPE, class OP>
static inline void NullaryScatterLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data,
const SelectionVector &ssel, idx_t count) {
for (idx_t i = 0; i < count; i++) {
auto sidx = ssel.get_index(i);
OP::template Operation<STATE_TYPE, OP>(states[sidx], aggr_input_data, sidx);
}
}
template <class STATE_TYPE, class INPUT_TYPE, class OP>
static inline void UnaryFlatLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
STATE_TYPE **__restrict states, ValidityMask &mask, idx_t count) {
if (!mask.AllValid()) {
idx_t base_idx = 0;
auto entry_count = ValidityMask::EntryCount(count);
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
auto validity_entry = mask.GetValidityEntry(entry_idx);
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) {
for (; base_idx < next; base_idx++) {
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[base_idx], aggr_input_data, idata,
mask, base_idx);
}
} else if (ValidityMask::NoneValid(validity_entry)) {
base_idx = next;
continue;
} else {
idx_t start = base_idx;
for (; base_idx < next; base_idx++) {
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[base_idx], aggr_input_data, idata,
mask, base_idx);
}
}
}
}
} else {
for (idx_t i = 0; i < count; i++) {
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[i], aggr_input_data, idata, mask, i);
}
}
}
template <class STATE_TYPE, class INPUT_TYPE, class OP>
static inline void UnaryScatterLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
STATE_TYPE **__restrict states, const SelectionVector &isel,
const SelectionVector &ssel, ValidityMask &mask, idx_t count) {
if (OP::IgnoreNull() && !mask.AllValid()) {
for (idx_t i = 0; i < count; i++) {
auto idx = isel.get_index(i);
auto sidx = ssel.get_index(i);
if (mask.RowIsValid(idx)) {
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, idata, mask, idx);
}
}
} else {
for (idx_t i = 0; i < count; i++) {
auto idx = isel.get_index(i);
auto sidx = ssel.get_index(i);
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, idata, mask, idx);
}
}
}
template <class STATE_TYPE, class INPUT_TYPE, class OP>
static inline void UnaryFlatUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask) {
idx_t base_idx = 0;
auto entry_count = ValidityMask::EntryCount(count);
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
auto validity_entry = mask.GetValidityEntry(entry_idx);
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) {
for (; base_idx < next; base_idx++) {
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask, base_idx);
}
} else if (ValidityMask::NoneValid(validity_entry)) {
base_idx = next;
continue;
} else {
idx_t start = base_idx;
for (; base_idx < next; base_idx++) {
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask,
base_idx);
}
}
}
}
}
template <class STATE_TYPE, class INPUT_TYPE, class OP>
static inline void UnaryUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask,
const SelectionVector &__restrict sel_vector) {
if (OP::IgnoreNull() && !mask.AllValid()) {
for (idx_t i = 0; i < count; i++) {
auto idx = sel_vector.get_index(i);
if (mask.RowIsValid(idx)) {
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask, idx);
}
}
} else {
for (idx_t i = 0; i < count; i++) {
auto idx = sel_vector.get_index(i);
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask, idx);
}
}
}
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
static inline void BinaryScatterLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data,
B_TYPE *__restrict bdata, STATE_TYPE **__restrict states, idx_t count,
const SelectionVector &asel, const SelectionVector &bsel,
const SelectionVector &ssel, ValidityMask &avalidity,
ValidityMask &bvalidity) {
if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) {
for (idx_t i = 0; i < count; i++) {
auto aidx = asel.get_index(i);
auto bidx = bsel.get_index(i);
auto sidx = ssel.get_index(i);
if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) {
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, adata, bdata,
avalidity, bvalidity, aidx, bidx);
}
}
} else {
for (idx_t i = 0; i < count; i++) {
auto aidx = asel.get_index(i);
auto bidx = bsel.get_index(i);
auto sidx = ssel.get_index(i);
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, adata, bdata,
avalidity, bvalidity, aidx, bidx);
}
}
}
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
static inline void BinaryUpdateLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data,
B_TYPE *__restrict bdata, STATE_TYPE *__restrict state, idx_t count,
const SelectionVector &asel, const SelectionVector &bsel,
ValidityMask &avalidity, ValidityMask &bvalidity) {
if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) {
for (idx_t i = 0; i < count; i++) {
auto aidx = asel.get_index(i);
auto bidx = bsel.get_index(i);
if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) {
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, aggr_input_data, adata, bdata,
avalidity, bvalidity, aidx, bidx);
}
}
} else {
for (idx_t i = 0; i < count; i++) {
auto aidx = asel.get_index(i);
auto bidx = bsel.get_index(i);
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, aggr_input_data, adata, bdata, avalidity,
bvalidity, aidx, bidx);
}
}
}
public:
template <class STATE_TYPE, class OP>
static void NullaryScatter(Vector &states, AggregateInputData &aggr_input_data, idx_t count) {
if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
OP::template ConstantOperation<STATE_TYPE, OP>(*sdata, aggr_input_data, count);
} else if (states.GetVectorType() == VectorType::FLAT_VECTOR) {
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
NullaryFlatLoop<STATE_TYPE, OP>(sdata, aggr_input_data, count);
} else {
UnifiedVectorFormat sdata;
states.ToUnifiedFormat(count, sdata);
NullaryScatterLoop<STATE_TYPE, OP>((STATE_TYPE **)sdata.data, aggr_input_data, *sdata.sel, count);
}
}
template <class STATE_TYPE, class OP>
static void NullaryUpdate(data_ptr_t state, AggregateInputData &aggr_input_data, idx_t count) {
OP::template ConstantOperation<STATE_TYPE, OP>((STATE_TYPE *)state, aggr_input_data, count);
}
template <class STATE_TYPE, class INPUT_TYPE, class OP>
static void UnaryScatter(Vector &input, Vector &states, AggregateInputData &aggr_input_data, idx_t count) {
if (input.GetVectorType() == VectorType::CONSTANT_VECTOR &&
states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
return;
}
auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>(*sdata, aggr_input_data, idata,
ConstantVector::Validity(input), count);
} else if (input.GetVectorType() == VectorType::FLAT_VECTOR &&
states.GetVectorType() == VectorType::FLAT_VECTOR) {
auto idata = FlatVector::GetData<INPUT_TYPE>(input);
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
UnaryFlatLoop<STATE_TYPE, INPUT_TYPE, OP>(idata, aggr_input_data, sdata, FlatVector::Validity(input),
count);
} else {
UnifiedVectorFormat idata, sdata;
input.ToUnifiedFormat(count, idata);
states.ToUnifiedFormat(count, sdata);
UnaryScatterLoop<STATE_TYPE, INPUT_TYPE, OP>((INPUT_TYPE *)idata.data, aggr_input_data,
(STATE_TYPE **)sdata.data, *idata.sel, *sdata.sel,
idata.validity, count);
}
}
template <class STATE_TYPE, class INPUT_TYPE, class OP>
static void UnaryUpdate(Vector &input, AggregateInputData &aggr_input_data, data_ptr_t state, idx_t count) {
switch (input.GetVectorType()) {
case VectorType::CONSTANT_VECTOR: {
if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
return;
}
auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>((STATE_TYPE *)state, aggr_input_data, idata,
ConstantVector::Validity(input), count);
break;
}
case VectorType::FLAT_VECTOR: {
auto idata = FlatVector::GetData<INPUT_TYPE>(input);
UnaryFlatUpdateLoop<STATE_TYPE, INPUT_TYPE, OP>(idata, aggr_input_data, (STATE_TYPE *)state, count,
FlatVector::Validity(input));
break;
}
default: {
UnifiedVectorFormat idata;
input.ToUnifiedFormat(count, idata);
UnaryUpdateLoop<STATE_TYPE, INPUT_TYPE, OP>((INPUT_TYPE *)idata.data, aggr_input_data, (STATE_TYPE *)state,
count, idata.validity, *idata.sel);
break;
}
}
}
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
static void BinaryScatter(AggregateInputData &aggr_input_data, Vector &a, Vector &b, Vector &states, idx_t count) {
UnifiedVectorFormat adata, bdata, sdata;
a.ToUnifiedFormat(count, adata);
b.ToUnifiedFormat(count, bdata);
states.ToUnifiedFormat(count, sdata);
BinaryScatterLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data,
(STATE_TYPE **)sdata.data, count, *adata.sel, *bdata.sel,
*sdata.sel, adata.validity, bdata.validity);
}
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
static void BinaryUpdate(AggregateInputData &aggr_input_data, Vector &a, Vector &b, data_ptr_t state, idx_t count) {
UnifiedVectorFormat adata, bdata;
a.ToUnifiedFormat(count, adata);
b.ToUnifiedFormat(count, bdata);
BinaryUpdateLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data,
(STATE_TYPE *)state, count, *adata.sel, *bdata.sel,
adata.validity, bdata.validity);
}
template <class STATE_TYPE, class OP>
static void Combine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) {
D_ASSERT(source.GetType().id() == LogicalTypeId::POINTER && target.GetType().id() == LogicalTypeId::POINTER);
auto sdata = FlatVector::GetData<const STATE_TYPE *>(source);
auto tdata = FlatVector::GetData<STATE_TYPE *>(target);
for (idx_t i = 0; i < count; i++) {
OP::template Combine<STATE_TYPE, OP>(*sdata[i], tdata[i], aggr_input_data);
}
}
template <class STATE_TYPE, class RESULT_TYPE, class OP>
static void Finalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count,
idx_t offset) {
if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
result.SetVectorType(VectorType::CONSTANT_VECTOR);
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
auto rdata = ConstantVector::GetData<RESULT_TYPE>(result);
OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, aggr_input_data, *sdata, rdata,
ConstantVector::Validity(result), 0);
} else {
D_ASSERT(states.GetVectorType() == VectorType::FLAT_VECTOR);
result.SetVectorType(VectorType::FLAT_VECTOR);
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
auto rdata = FlatVector::GetData<RESULT_TYPE>(result);
for (idx_t i = 0; i < count; i++) {
OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, aggr_input_data, sdata[i], rdata,
FlatVector::Validity(result), i + offset);
}
}
}
template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
static void UnaryWindow(Vector &input, const ValidityMask &ifilter, AggregateInputData &aggr_input_data,
data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, Vector &result,
idx_t rid, idx_t bias) {
auto idata = FlatVector::GetData<const INPUT_TYPE>(input) - bias;
const auto &ivalid = FlatVector::Validity(input);
OP::template Window<STATE, INPUT_TYPE, RESULT_TYPE>(idata, ifilter, ivalid, aggr_input_data, (STATE *)state,
frame, prev, result, rid, bias);
}
template <class STATE_TYPE, class OP>
static void Destroy(Vector &states, idx_t count) {
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
for (idx_t i = 0; i < count; i++) {
OP::template Destroy<STATE_TYPE>(sdata[i]);
}
}
};
}
namespace duckdb {
enum class AggregateType : uint8_t { NON_DISTINCT = 1, DISTINCT = 2 };
class BoundAggregateExpression;
struct AggregateInputData {
AggregateInputData(FunctionData *bind_data_p, Allocator &allocator_p)
: bind_data(bind_data_p), allocator(allocator_p) {};
FunctionData *bind_data;
Allocator &allocator;
};
typedef idx_t (*aggregate_size_t)();
typedef void (*aggregate_initialize_t)(data_ptr_t state);
typedef void (*aggregate_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
Vector &state, idx_t count);
typedef void (*aggregate_combine_t)(Vector &state, Vector &combined, AggregateInputData &aggr_input_data, idx_t count);
typedef void (*aggregate_finalize_t)(Vector &state, AggregateInputData &aggr_input_data, Vector &result, idx_t count,
idx_t offset);
typedef unique_ptr<BaseStatistics> (*aggregate_statistics_t)(ClientContext &context, BoundAggregateExpression &expr,
FunctionData *bind_data,
vector<unique_ptr<BaseStatistics>> &child_stats,
NodeStatistics *node_stats);
typedef unique_ptr<FunctionData> (*bind_aggregate_function_t)(ClientContext &context, AggregateFunction &function,
vector<unique_ptr<Expression>> &arguments);
typedef void (*aggregate_destructor_t)(Vector &state, idx_t count);
typedef void (*aggregate_simple_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
data_ptr_t state, idx_t count);
typedef std::pair<idx_t, idx_t> FrameBounds;
typedef void (*aggregate_window_t)(Vector inputs[], const ValidityMask &filter_mask,
AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid,
idx_t bias);
typedef void (*aggregate_serialize_t)(FieldWriter &writer, const FunctionData *bind_data,
const AggregateFunction &function);
typedef unique_ptr<FunctionData> (*aggregate_deserialize_t)(ClientContext &context, FieldReader &reader,
AggregateFunction &function);
class AggregateFunction : public BaseScalarFunction {
public:
DUCKDB_API
AggregateFunction(const string &name, const vector<LogicalType> &arguments, const LogicalType &return_type,
aggregate_size_t state_size, aggregate_initialize_t initialize, aggregate_update_t update,
aggregate_combine_t combine, aggregate_finalize_t finalize,
FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING,
aggregate_simple_update_t simple_update = nullptr, bind_aggregate_function_t bind = nullptr,
aggregate_destructor_t destructor = nullptr, aggregate_statistics_t statistics = nullptr,
aggregate_window_t window = nullptr, aggregate_serialize_t serialize = nullptr,
aggregate_deserialize_t deserialize = nullptr)
: BaseScalarFunction(name, arguments, return_type, FunctionSideEffects::NO_SIDE_EFFECTS,
LogicalType(LogicalTypeId::INVALID), null_handling),
state_size(state_size), initialize(initialize), update(update), combine(combine), finalize(finalize),
simple_update(simple_update), window(window), bind(bind), destructor(destructor), statistics(statistics),
serialize(serialize), deserialize(deserialize) {
}
DUCKDB_API
AggregateFunction(const string &name, const vector<LogicalType> &arguments, const LogicalType &return_type,
aggregate_size_t state_size, aggregate_initialize_t initialize, aggregate_update_t update,
aggregate_combine_t combine, aggregate_finalize_t finalize,
aggregate_simple_update_t simple_update = nullptr, bind_aggregate_function_t bind = nullptr,
aggregate_destructor_t destructor = nullptr, aggregate_statistics_t statistics = nullptr,
aggregate_window_t window = nullptr, aggregate_serialize_t serialize = nullptr,
aggregate_deserialize_t deserialize = nullptr)
: BaseScalarFunction(name, arguments, return_type, FunctionSideEffects::NO_SIDE_EFFECTS,
LogicalType(LogicalTypeId::INVALID)),
state_size(state_size), initialize(initialize), update(update), combine(combine), finalize(finalize),
simple_update(simple_update), window(window), bind(bind), destructor(destructor), statistics(statistics),
serialize(serialize), deserialize(deserialize) {
}
DUCKDB_API AggregateFunction(const vector<LogicalType> &arguments, const LogicalType &return_type,
aggregate_size_t state_size, aggregate_initialize_t initialize,
aggregate_update_t update, aggregate_combine_t combine, aggregate_finalize_t finalize,
FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING,
aggregate_simple_update_t simple_update = nullptr,
bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr,
aggregate_statistics_t statistics = nullptr, aggregate_window_t window = nullptr,
aggregate_serialize_t serialize = nullptr,
aggregate_deserialize_t deserialize = nullptr)
: AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize,
null_handling, simple_update, bind, destructor, statistics, window, serialize,
deserialize) {
}
DUCKDB_API
AggregateFunction(const vector<LogicalType> &arguments, const LogicalType &return_type, aggregate_size_t state_size,
aggregate_initialize_t initialize, aggregate_update_t update, aggregate_combine_t combine,
aggregate_finalize_t finalize, aggregate_simple_update_t simple_update = nullptr,
bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr,
aggregate_statistics_t statistics = nullptr, aggregate_window_t window = nullptr,
aggregate_serialize_t serialize = nullptr, aggregate_deserialize_t deserialize = nullptr)
: AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize,
FunctionNullHandling::DEFAULT_NULL_HANDLING, simple_update, bind, destructor, statistics,
window, serialize, deserialize) {
}
aggregate_size_t state_size;
aggregate_initialize_t initialize;
aggregate_update_t update;
aggregate_combine_t combine;
aggregate_finalize_t finalize;
aggregate_simple_update_t simple_update;
aggregate_window_t window;
bind_aggregate_function_t bind;
aggregate_destructor_t destructor;
aggregate_statistics_t statistics;
aggregate_serialize_t serialize;
aggregate_deserialize_t deserialize;
DUCKDB_API bool operator==(const AggregateFunction &rhs) const {
return state_size == rhs.state_size && initialize == rhs.initialize && update == rhs.update &&
combine == rhs.combine && finalize == rhs.finalize && window == rhs.window;
}
DUCKDB_API bool operator!=(const AggregateFunction &rhs) const {
return !(*this == rhs);
}
public:
template <class STATE, class RESULT_TYPE, class OP>
static AggregateFunction NullaryAggregate(LogicalType return_type) {
return AggregateFunction(
{}, return_type, AggregateFunction::StateSize<STATE>, AggregateFunction::StateInitialize<STATE, OP>,
AggregateFunction::NullaryScatterUpdate<STATE, OP>, AggregateFunction::StateCombine<STATE, OP>,
AggregateFunction::StateFinalize<STATE, RESULT_TYPE, OP>, AggregateFunction::NullaryUpdate<STATE, OP>);
}
template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
static AggregateFunction
UnaryAggregate(const LogicalType &input_type, LogicalType return_type,
FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING) {
return AggregateFunction(
{input_type}, return_type, AggregateFunction::StateSize<STATE>,
AggregateFunction::StateInitialize<STATE, OP>, AggregateFunction::UnaryScatterUpdate<STATE, INPUT_TYPE, OP>,
AggregateFunction::StateCombine<STATE, OP>, AggregateFunction::StateFinalize<STATE, RESULT_TYPE, OP>,
null_handling, AggregateFunction::UnaryUpdate<STATE, INPUT_TYPE, OP>);
}
template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
static AggregateFunction UnaryAggregateDestructor(LogicalType input_type, LogicalType return_type) {
auto aggregate = UnaryAggregate<STATE, INPUT_TYPE, RESULT_TYPE, OP>(input_type, return_type);
aggregate.destructor = AggregateFunction::StateDestroy<STATE, OP>;
return aggregate;
}
template <class STATE, class A_TYPE, class B_TYPE, class RESULT_TYPE, class OP>
static AggregateFunction BinaryAggregate(const LogicalType &a_type, const LogicalType &b_type,
LogicalType return_type) {
return AggregateFunction({a_type, b_type}, return_type, AggregateFunction::StateSize<STATE>,
AggregateFunction::StateInitialize<STATE, OP>,
AggregateFunction::BinaryScatterUpdate<STATE, A_TYPE, B_TYPE, OP>,
AggregateFunction::StateCombine<STATE, OP>,
AggregateFunction::StateFinalize<STATE, RESULT_TYPE, OP>,
AggregateFunction::BinaryUpdate<STATE, A_TYPE, B_TYPE, OP>);
}
public:
template <class STATE>
static idx_t StateSize() {
return sizeof(STATE);
}
template <class STATE, class OP>
static void StateInitialize(data_ptr_t state) {
OP::Initialize((STATE *)state);
}
template <class STATE, class OP>
static void NullaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
Vector &states, idx_t count) {
D_ASSERT(input_count == 0);
AggregateExecutor::NullaryScatter<STATE, OP>(states, aggr_input_data, count);
}
template <class STATE, class OP>
static void NullaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
idx_t count) {
D_ASSERT(input_count == 0);
AggregateExecutor::NullaryUpdate<STATE, OP>(state, aggr_input_data, count);
}
template <class STATE, class T, class OP>
static void UnaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
Vector &states, idx_t count) {
D_ASSERT(input_count == 1);
AggregateExecutor::UnaryScatter<STATE, T, OP>(inputs[0], states, aggr_input_data, count);
}
template <class STATE, class INPUT_TYPE, class OP>
static void UnaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
idx_t count) {
D_ASSERT(input_count == 1);
AggregateExecutor::UnaryUpdate<STATE, INPUT_TYPE, OP>(inputs[0], aggr_input_data, state, count);
}
template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
static void UnaryWindow(Vector inputs[], const ValidityMask &filter_mask, AggregateInputData &aggr_input_data,
idx_t input_count, data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev,
Vector &result, idx_t rid, idx_t bias) {
D_ASSERT(input_count == 1);
AggregateExecutor::UnaryWindow<STATE, INPUT_TYPE, RESULT_TYPE, OP>(inputs[0], filter_mask, aggr_input_data,
state, frame, prev, result, rid, bias);
}
template <class STATE, class A_TYPE, class B_TYPE, class OP>
static void BinaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
Vector &states, idx_t count) {
D_ASSERT(input_count == 2);
AggregateExecutor::BinaryScatter<STATE, A_TYPE, B_TYPE, OP>(aggr_input_data, inputs[0], inputs[1], states,
count);
}
template <class STATE, class A_TYPE, class B_TYPE, class OP>
static void BinaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
idx_t count) {
D_ASSERT(input_count == 2);
AggregateExecutor::BinaryUpdate<STATE, A_TYPE, B_TYPE, OP>(aggr_input_data, inputs[0], inputs[1], state, count);
}
template <class STATE, class OP>
static void StateCombine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) {
AggregateExecutor::Combine<STATE, OP>(source, target, aggr_input_data, count);
}
template <class STATE, class RESULT_TYPE, class OP>
static void StateFinalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count,
idx_t offset) {
AggregateExecutor::Finalize<STATE, RESULT_TYPE, OP>(states, aggr_input_data, result, count, offset);
}
template <class STATE, class OP>
static void StateDestroy(Vector &states, idx_t count) {
AggregateExecutor::Destroy<STATE, OP>(states, count);
}
};
}
namespace duckdb {
struct UDFWrapper {
public:
template <typename TR, typename... Args>
static scalar_function_t CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) {
const std::size_t num_template_argc = sizeof...(Args);
switch (num_template_argc) {
case 1:
return CreateUnaryFunction<TR, Args...>(name, udf_func);
case 2:
return CreateBinaryFunction<TR, Args...>(name, udf_func);
case 3:
return CreateTernaryFunction<TR, Args...>(name, udf_func);
default: throw std::runtime_error("UDF function only supported until ternary!");
} }
template <typename TR, typename... Args>
static scalar_function_t CreateScalarFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(Args...)) {
if (!TypesMatch<TR>(ret_type)) { throw std::runtime_error("Return type doesn't match with the first template type.");
}
const std::size_t num_template_types = sizeof...(Args);
if (num_template_types != args.size()) { throw std::runtime_error(
"The number of templated types should be the same quantity of the LogicalType arguments.");
}
switch (num_template_types) {
case 1:
return CreateUnaryFunction<TR, Args...>(name, args, ret_type, udf_func);
case 2:
return CreateBinaryFunction<TR, Args...>(name, args, ret_type, udf_func);
case 3:
return CreateTernaryFunction<TR, Args...>(name, args, ret_type, udf_func);
default: throw std::runtime_error("UDF function only supported until ternary!");
} }
template <typename TR, typename... Args>
static void RegisterFunction(const string &name, scalar_function_t udf_function, ClientContext &context,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) {
vector<LogicalType> arguments;
GetArgumentTypesRecursive<Args...>(arguments);
LogicalType ret_type = GetArgumentType<TR>();
RegisterFunction(name, arguments, ret_type, udf_function, context, varargs);
}
DUCKDB_API static void RegisterFunction(string name, vector<LogicalType> args, LogicalType ret_type,
scalar_function_t udf_function, ClientContext &context,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID));
template <typename UDF_OP, typename STATE, typename TR, typename TA>
static AggregateFunction CreateAggregateFunction(const string &name) {
return CreateUnaryAggregateFunction<UDF_OP, STATE, TR, TA>(name);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB>
static AggregateFunction CreateAggregateFunction(const string &name) {
return CreateBinaryAggregateFunction<UDF_OP, STATE, TR, TA, TB>(name);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA>
static AggregateFunction CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_type) {
if (!TypesMatch<TR>(ret_type)) { throw std::runtime_error("The return argument don't match!");
}
if (!TypesMatch<TA>(input_type)) { throw std::runtime_error("The input argument don't match!");
}
return CreateUnaryAggregateFunction<UDF_OP, STATE, TR, TA>(name, ret_type, input_type);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB>
static AggregateFunction CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA,
LogicalType input_typeB) {
if (!TypesMatch<TR>(ret_type)) { throw std::runtime_error("The return argument don't match!");
}
if (!TypesMatch<TA>(input_typeA)) {
throw std::runtime_error("The first input argument don't match!");
}
if (!TypesMatch<TB>(input_typeB)) {
throw std::runtime_error("The second input argument don't match!");
}
return CreateBinaryAggregateFunction<UDF_OP, STATE, TR, TA, TB>(name, ret_type, input_typeA, input_typeB);
}
static AggregateFunction CreateAggregateFunction(string name, vector<LogicalType> arguments,
LogicalType return_type, aggregate_size_t state_size,
aggregate_initialize_t initialize, aggregate_update_t update,
aggregate_combine_t combine, aggregate_finalize_t finalize,
aggregate_simple_update_t simple_update = nullptr,
bind_aggregate_function_t bind = nullptr,
aggregate_destructor_t destructor = nullptr) {
AggregateFunction aggr_function(std::move(name), std::move(arguments), std::move(return_type), state_size,
initialize, update, combine, finalize, simple_update, bind, destructor);
aggr_function.null_handling = FunctionNullHandling::SPECIAL_HANDLING;
return aggr_function;
}
DUCKDB_API static void RegisterAggrFunction(AggregateFunction aggr_function, ClientContext &context,
LogicalType varargs = LogicalType(LogicalTypeId::INVALID));
private:
struct UnaryUDFExecutor {
template <class INPUT_TYPE, class RESULT_TYPE>
static RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
typedef RESULT_TYPE (*unary_function_t)(INPUT_TYPE);
auto udf = (unary_function_t)dataptr;
return udf(input);
}
};
template <typename TR, typename TA>
static scalar_function_t CreateUnaryFunction(const string &name, TR (*udf_func)(TA)) {
scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void {
UnaryExecutor::GenericExecute<TA, TR, UnaryUDFExecutor>(input.data[0], result, input.size(),
(void *)udf_func);
};
return udf_function;
}
template <typename TR, typename TA, typename TB>
static scalar_function_t CreateBinaryFunction(const string &name, TR (*udf_func)(TA, TB)) {
scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void {
BinaryExecutor::Execute<TA, TB, TR>(input.data[0], input.data[1], result, input.size(), udf_func);
};
return udf_function;
}
template <typename TR, typename TA, typename TB, typename TC>
static scalar_function_t CreateTernaryFunction(const string &name, TR (*udf_func)(TA, TB, TC)) {
scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void {
TernaryExecutor::Execute<TA, TB, TC, TR>(input.data[0], input.data[1], input.data[2], result, input.size(),
udf_func);
};
return udf_function;
}
template <typename TR, typename... Args>
static scalar_function_t CreateUnaryFunction(const string &name, TR (*udf_func)(Args...)) { throw std::runtime_error("Incorrect number of arguments for unary function");
}
template <typename TR, typename... Args>
static scalar_function_t CreateBinaryFunction(const string &name, TR (*udf_func)(Args...)) { throw std::runtime_error("Incorrect number of arguments for binary function");
}
template <typename TR, typename... Args>
static scalar_function_t CreateTernaryFunction(const string &name, TR (*udf_func)(Args...)) { throw std::runtime_error("Incorrect number of arguments for ternary function");
}
template <typename T>
static LogicalType GetArgumentType() {
if (std::is_same<T, bool>()) {
return LogicalType(LogicalTypeId::BOOLEAN);
} else if (std::is_same<T, int8_t>()) {
return LogicalType(LogicalTypeId::TINYINT);
} else if (std::is_same<T, int16_t>()) {
return LogicalType(LogicalTypeId::SMALLINT);
} else if (std::is_same<T, int32_t>()) {
return LogicalType(LogicalTypeId::INTEGER);
} else if (std::is_same<T, int64_t>()) {
return LogicalType(LogicalTypeId::BIGINT);
} else if (std::is_same<T, float>()) {
return LogicalType(LogicalTypeId::FLOAT);
} else if (std::is_same<T, double>()) {
return LogicalType(LogicalTypeId::DOUBLE);
} else if (std::is_same<T, string_t>()) {
return LogicalType(LogicalTypeId::VARCHAR);
} else { throw std::runtime_error("Unrecognized type!");
} }
template <typename TA, typename TB, typename... Args>
static void GetArgumentTypesRecursive(vector<LogicalType> &arguments) {
arguments.push_back(GetArgumentType<TA>());
GetArgumentTypesRecursive<TB, Args...>(arguments);
}
template <typename TA>
static void GetArgumentTypesRecursive(vector<LogicalType> &arguments) {
arguments.push_back(GetArgumentType<TA>());
}
private:
template <typename TR, typename... Args>
static scalar_function_t CreateUnaryFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(Args...)) { throw std::runtime_error("Incorrect number of arguments for unary function");
}
template <typename TR, typename TA>
static scalar_function_t CreateUnaryFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(TA)) {
if (args.size() != 1) { throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 1!");
}
if (!TypesMatch<TA>(args[0])) {
throw std::runtime_error("The first arguments don't match!");
}
scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void {
UnaryExecutor::GenericExecute<TA, TR, UnaryUDFExecutor>(input.data[0], result, input.size(),
(void *)udf_func);
};
return udf_function;
}
template <typename TR, typename... Args>
static scalar_function_t CreateBinaryFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(Args...)) { throw std::runtime_error("Incorrect number of arguments for binary function");
}
template <typename TR, typename TA, typename TB>
static scalar_function_t CreateBinaryFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(TA, TB)) {
if (args.size() != 2) { throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 2!");
}
if (!TypesMatch<TA>(args[0])) {
throw std::runtime_error("The first arguments don't match!");
}
if (!TypesMatch<TB>(args[1])) {
throw std::runtime_error("The second arguments don't match!");
}
scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) {
BinaryExecutor::Execute<TA, TB, TR>(input.data[0], input.data[1], result, input.size(), udf_func);
};
return udf_function;
}
template <typename TR, typename... Args>
static scalar_function_t CreateTernaryFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(Args...)) { throw std::runtime_error("Incorrect number of arguments for ternary function");
}
template <typename TR, typename TA, typename TB, typename TC>
static scalar_function_t CreateTernaryFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(TA, TB, TC)) {
if (args.size() != 3) { throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 3!");
}
if (!TypesMatch<TA>(args[0])) {
throw std::runtime_error("The first arguments don't match!");
}
if (!TypesMatch<TB>(args[1])) {
throw std::runtime_error("The second arguments don't match!");
}
if (!TypesMatch<TC>(args[2])) {
throw std::runtime_error("The second arguments don't match!");
}
scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void {
TernaryExecutor::Execute<TA, TB, TC, TR>(input.data[0], input.data[1], input.data[2], result, input.size(),
udf_func);
};
return udf_function;
}
template <typename T>
static bool TypesMatch(const LogicalType &sql_type) {
switch (sql_type.id()) {
case LogicalTypeId::BOOLEAN:
return std::is_same<T, bool>();
case LogicalTypeId::TINYINT:
return std::is_same<T, int8_t>();
case LogicalTypeId::SMALLINT:
return std::is_same<T, int16_t>();
case LogicalTypeId::INTEGER:
return std::is_same<T, int32_t>();
case LogicalTypeId::BIGINT:
return std::is_same<T, int64_t>();
case LogicalTypeId::DATE:
return std::is_same<T, date_t>();
case LogicalTypeId::TIME:
case LogicalTypeId::TIME_TZ:
return std::is_same<T, dtime_t>();
case LogicalTypeId::TIMESTAMP:
case LogicalTypeId::TIMESTAMP_MS:
case LogicalTypeId::TIMESTAMP_NS:
case LogicalTypeId::TIMESTAMP_SEC:
case LogicalTypeId::TIMESTAMP_TZ:
return std::is_same<T, timestamp_t>();
case LogicalTypeId::FLOAT:
return std::is_same<T, float>();
case LogicalTypeId::DOUBLE:
return std::is_same<T, double>();
case LogicalTypeId::VARCHAR:
case LogicalTypeId::CHAR:
case LogicalTypeId::BLOB:
return std::is_same<T, string_t>();
default: throw std::runtime_error("Type is not supported!");
} }
private:
template <typename UDF_OP, typename STATE, typename TR, typename TA>
static AggregateFunction CreateUnaryAggregateFunction(const string &name) {
LogicalType return_type = GetArgumentType<TR>();
LogicalType input_type = GetArgumentType<TA>();
return CreateUnaryAggregateFunction<UDF_OP, STATE, TR, TA>(name, return_type, input_type);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA>
static AggregateFunction CreateUnaryAggregateFunction(const string &name, LogicalType ret_type,
LogicalType input_type) {
AggregateFunction aggr_function =
AggregateFunction::UnaryAggregate<STATE, TR, TA, UDF_OP>(input_type, ret_type);
aggr_function.name = name;
return aggr_function;
}
template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB>
static AggregateFunction CreateBinaryAggregateFunction(const string &name) {
LogicalType return_type = GetArgumentType<TR>();
LogicalType input_typeA = GetArgumentType<TA>();
LogicalType input_typeB = GetArgumentType<TB>();
return CreateBinaryAggregateFunction<UDF_OP, STATE, TR, TA, TB>(name, return_type, input_typeA, input_typeB);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB>
static AggregateFunction CreateBinaryAggregateFunction(const string &name, LogicalType ret_type,
LogicalType input_typeA, LogicalType input_typeB) {
AggregateFunction aggr_function =
AggregateFunction::BinaryAggregate<STATE, TR, TA, TB, UDF_OP>(input_typeA, input_typeB, ret_type);
aggr_function.name = name;
return aggr_function;
}
};
}
#include <utility>
namespace duckdb {
using std::make_pair;
using std::pair;
}
#include <mutex>
namespace duckdb {
using std::lock_guard;
using std::mutex;
using std::unique_lock;
}
namespace duckdb {
enum class ColumnDataAllocatorType : uint8_t {
BUFFER_MANAGER_ALLOCATOR,
IN_MEMORY_ALLOCATOR
};
enum class ColumnDataScanProperties : uint8_t {
INVALID,
ALLOW_ZERO_COPY,
DISALLOW_ZERO_COPY
};
struct ChunkManagementState {
unordered_map<idx_t, BufferHandle> handles;
ColumnDataScanProperties properties = ColumnDataScanProperties::INVALID;
};
struct ColumnDataAppendState {
ChunkManagementState current_chunk_state;
vector<UnifiedVectorFormat> vector_data;
};
struct ColumnDataScanState {
ChunkManagementState current_chunk_state;
idx_t segment_index;
idx_t chunk_index;
idx_t current_row_index;
idx_t next_row_index;
ColumnDataScanProperties properties;
vector<column_t> column_ids;
};
struct ColumnDataParallelScanState {
ColumnDataScanState scan_state;
mutex lock;
};
struct ColumnDataLocalScanState {
ChunkManagementState current_chunk_state;
idx_t current_segment_index = DConstants::INVALID_INDEX;
idx_t current_row_index;
};
class ColumnDataRow {
public:
ColumnDataRow(DataChunk &chunk, idx_t row_index, idx_t base_index);
DataChunk &chunk;
idx_t row_index;
idx_t base_index;
public:
Value GetValue(idx_t column_index) const;
idx_t RowIndex() const;
};
}
namespace duckdb {
class ColumnDataCollection;
class ColumnDataChunkIterationHelper {
public:
DUCKDB_API ColumnDataChunkIterationHelper(const ColumnDataCollection &collection, vector<column_t> column_ids);
private:
const ColumnDataCollection &collection;
vector<column_t> column_ids;
private:
class ColumnDataChunkIterator;
class ColumnDataChunkIterator {
public:
DUCKDB_API explicit ColumnDataChunkIterator(const ColumnDataCollection *collection_p,
vector<column_t> column_ids);
const ColumnDataCollection *collection;
ColumnDataScanState scan_state;
shared_ptr<DataChunk> scan_chunk;
idx_t row_index;
public:
DUCKDB_API void Next();
DUCKDB_API ColumnDataChunkIterator &operator++();
DUCKDB_API bool operator!=(const ColumnDataChunkIterator &other) const;
DUCKDB_API DataChunk &operator*() const;
};
public:
DUCKDB_API ColumnDataChunkIterator begin() {
return ColumnDataChunkIterator(&collection, column_ids);
}
DUCKDB_API ColumnDataChunkIterator end() {
return ColumnDataChunkIterator(nullptr, vector<column_t>());
}
};
class ColumnDataRowIterationHelper {
public:
DUCKDB_API ColumnDataRowIterationHelper(const ColumnDataCollection &collection);
private:
const ColumnDataCollection &collection;
private:
class ColumnDataRowIterator;
class ColumnDataRowIterator {
public:
DUCKDB_API explicit ColumnDataRowIterator(const ColumnDataCollection *collection_p);
const ColumnDataCollection *collection;
ColumnDataScanState scan_state;
shared_ptr<DataChunk> scan_chunk;
ColumnDataRow current_row;
public:
void Next();
DUCKDB_API ColumnDataRowIterator &operator++();
DUCKDB_API bool operator!=(const ColumnDataRowIterator &other) const;
DUCKDB_API const ColumnDataRow &operator*() const;
};
public:
DUCKDB_API ColumnDataRowIterator begin();
DUCKDB_API ColumnDataRowIterator end();
};
}
namespace duckdb {
class BufferManager;
class BlockHandle;
class ClientContext;
struct ColumnDataCopyFunction;
class ColumnDataAllocator;
class ColumnDataCollection;
class ColumnDataCollectionSegment;
class ColumnDataRowCollection;
class ColumnDataCollection {
public:
DUCKDB_API ColumnDataCollection(Allocator &allocator, vector<LogicalType> types);
DUCKDB_API ColumnDataCollection(Allocator &allocator);
DUCKDB_API ColumnDataCollection(BufferManager &buffer_manager, vector<LogicalType> types);
DUCKDB_API ColumnDataCollection(ClientContext &context, vector<LogicalType> types,
ColumnDataAllocatorType type = ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR);
DUCKDB_API ColumnDataCollection(ColumnDataCollection &parent);
DUCKDB_API ColumnDataCollection(shared_ptr<ColumnDataAllocator> allocator, vector<LogicalType> types);
DUCKDB_API ~ColumnDataCollection();
public:
DUCKDB_API vector<LogicalType> &Types() {
return types;
}
DUCKDB_API const vector<LogicalType> &Types() const {
return types;
}
DUCKDB_API const idx_t &Count() const {
return count;
}
DUCKDB_API idx_t ColumnCount() const {
return types.size();
}
DUCKDB_API Allocator &GetAllocator() const;
DUCKDB_API void InitializeAppend(ColumnDataAppendState &state);
DUCKDB_API void Append(ColumnDataAppendState &state, DataChunk &new_chunk);
DUCKDB_API void InitializeScanChunk(DataChunk &chunk) const;
DUCKDB_API void InitializeScanChunk(ColumnDataScanState &state, DataChunk &chunk) const;
DUCKDB_API void
InitializeScan(ColumnDataScanState &state,
ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const;
DUCKDB_API void
InitializeScan(ColumnDataScanState &state, vector<column_t> column_ids,
ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const;
DUCKDB_API void
InitializeScan(ColumnDataParallelScanState &state,
ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const;
DUCKDB_API void
InitializeScan(ColumnDataParallelScanState &state, vector<column_t> column_ids,
ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const;
DUCKDB_API bool Scan(ColumnDataScanState &state, DataChunk &result) const;
DUCKDB_API bool Scan(ColumnDataParallelScanState &state, ColumnDataLocalScanState &lstate, DataChunk &result) const;
DUCKDB_API void Append(DataChunk &new_chunk);
DUCKDB_API void Combine(ColumnDataCollection &other);
DUCKDB_API void Verify();
DUCKDB_API string ToString() const;
DUCKDB_API void Print() const;
DUCKDB_API void Reset();
DUCKDB_API idx_t ChunkCount() const;
DUCKDB_API void FetchChunk(idx_t chunk_idx, DataChunk &result) const;
DUCKDB_API ColumnDataChunkIterationHelper Chunks() const;
DUCKDB_API ColumnDataChunkIterationHelper Chunks(vector<column_t> column_ids) const;
DUCKDB_API ColumnDataRowIterationHelper Rows() const;
DUCKDB_API ColumnDataRowCollection GetRows() const;
static bool ResultEquals(const ColumnDataCollection &left, const ColumnDataCollection &right,
string &error_message);
bool NextScanIndex(ColumnDataScanState &state, idx_t &chunk_index, idx_t &segment_index, idx_t &row_index) const;
void ScanAtIndex(ColumnDataParallelScanState &state, ColumnDataLocalScanState &lstate, DataChunk &result,
idx_t chunk_index, idx_t segment_index, idx_t row_index) const;
void Initialize(vector<LogicalType> types);
const vector<unique_ptr<ColumnDataCollectionSegment>> &GetSegments() const;
private:
void CreateSegment();
static ColumnDataCopyFunction GetCopyFunction(const LogicalType &type);
private:
buffer_ptr<ColumnDataAllocator> allocator;
vector<LogicalType> types;
idx_t count;
vector<unique_ptr<ColumnDataCollectionSegment>> segments;
vector<ColumnDataCopyFunction> copy_functions;
bool finished_append;
};
class ColumnDataRowCollection {
public:
DUCKDB_API ColumnDataRowCollection(const ColumnDataCollection &collection);
public:
DUCKDB_API Value GetValue(idx_t column, idx_t index) const;
public:
DUCKDB_API bool empty() const {
return rows.empty();
}
DUCKDB_API idx_t size() const {
return rows.size();
}
DUCKDB_API ColumnDataRow &operator[](idx_t i);
DUCKDB_API const ColumnDataRow &operator[](idx_t i) const;
DUCKDB_API vector<ColumnDataRow>::iterator begin() {
return rows.begin();
}
DUCKDB_API vector<ColumnDataRow>::iterator end() {
return rows.end();
}
DUCKDB_API vector<ColumnDataRow>::const_iterator cbegin() const {
return rows.cbegin();
}
DUCKDB_API vector<ColumnDataRow>::const_iterator cend() const {
return rows.cend();
}
DUCKDB_API vector<ColumnDataRow>::const_iterator begin() const {
return rows.begin();
}
DUCKDB_API vector<ColumnDataRow>::const_iterator end() const {
return rows.end();
}
private:
vector<ColumnDataRow> rows;
vector<unique_ptr<DataChunk>> chunks;
ColumnDataScanState scan_state;
};
}
namespace duckdb {
enum class StatementType : uint8_t {
INVALID_STATEMENT, SELECT_STATEMENT, INSERT_STATEMENT, UPDATE_STATEMENT, CREATE_STATEMENT, DELETE_STATEMENT, PREPARE_STATEMENT, EXECUTE_STATEMENT, ALTER_STATEMENT, TRANSACTION_STATEMENT, COPY_STATEMENT, ANALYZE_STATEMENT, VARIABLE_SET_STATEMENT, CREATE_FUNC_STATEMENT, EXPLAIN_STATEMENT, DROP_STATEMENT, EXPORT_STATEMENT, PRAGMA_STATEMENT, SHOW_STATEMENT, VACUUM_STATEMENT, CALL_STATEMENT, SET_STATEMENT, LOAD_STATEMENT, RELATION_STATEMENT,
EXTENSION_STATEMENT,
LOGICAL_PLAN_STATEMENT,
ATTACH_STATEMENT,
DETACH_STATEMENT
};
DUCKDB_API string StatementTypeToString(StatementType type);
enum class StatementReturnType : uint8_t {
QUERY_RESULT, CHANGED_ROWS, NOTHING };
string StatementReturnTypeToString(StatementReturnType type);
struct StatementProperties {
StatementProperties()
: requires_valid_transaction(true), allow_stream_result(false), bound_all_parameters(true),
return_type(StatementReturnType::QUERY_RESULT), parameter_count(0) {
}
unordered_set<string> modified_databases;
bool requires_valid_transaction;
bool allow_stream_result;
bool bound_all_parameters;
StatementReturnType return_type;
idx_t parameter_count;
bool IsReadOnly() {
return modified_databases.empty();
}
};
}
namespace duckdb {
struct BoxRendererConfig;
enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, STREAM_RESULT, PENDING_RESULT };
struct ClientProperties {
string timezone;
};
class BaseQueryResult {
public:
DUCKDB_API BaseQueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties,
vector<LogicalType> types, vector<string> names);
DUCKDB_API BaseQueryResult(QueryResultType type, PreservedError error);
DUCKDB_API virtual ~BaseQueryResult();
QueryResultType type;
StatementType statement_type;
StatementProperties properties;
vector<LogicalType> types;
vector<string> names;
public:
DUCKDB_API void ThrowError(const string &prepended_message = "") const;
DUCKDB_API void SetError(PreservedError error);
DUCKDB_API bool HasError() const;
DUCKDB_API const ExceptionType &GetErrorType() const;
DUCKDB_API const std::string &GetError();
DUCKDB_API PreservedError &GetErrorObject();
DUCKDB_API idx_t ColumnCount();
protected:
bool success;
PreservedError error;
};
class QueryResult : public BaseQueryResult {
public:
DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties,
vector<LogicalType> types, vector<string> names, ClientProperties client_properties);
DUCKDB_API QueryResult(QueryResultType type, PreservedError error);
DUCKDB_API virtual ~QueryResult() override;
ClientProperties client_properties;
unique_ptr<QueryResult> next;
public:
DUCKDB_API const string &ColumnName(idx_t index) const;
DUCKDB_API virtual unique_ptr<DataChunk> Fetch();
DUCKDB_API virtual unique_ptr<DataChunk> FetchRaw() = 0;
DUCKDB_API virtual string ToString() = 0;
DUCKDB_API virtual string ToBox(ClientContext &context, const BoxRendererConfig &config);
DUCKDB_API void Print();
DUCKDB_API bool Equals(QueryResult &other);
DUCKDB_API bool TryFetch(unique_ptr<DataChunk> &result, PreservedError &error) {
try {
result = Fetch();
return success;
} catch (const Exception &ex) {
error = PreservedError(ex);
return false;
} catch (std::exception &ex) {
error = PreservedError(ex);
return false;
} catch (...) {
error = PreservedError("Unknown error in Fetch");
return false;
}
}
static string GetConfigTimezone(QueryResult &query_result);
private:
class QueryResultIterator;
class QueryResultRow {
public:
explicit QueryResultRow(QueryResultIterator &iterator_p, idx_t row_idx) : iterator(iterator_p), row(0) {
}
QueryResultIterator &iterator;
idx_t row;
template <class T>
T GetValue(idx_t col_idx) const {
return iterator.chunk->GetValue(col_idx, row).GetValue<T>();
}
};
class QueryResultIterator {
public:
explicit QueryResultIterator(QueryResult *result_p) : current_row(*this, 0), result(result_p), base_row(0) {
if (result) {
chunk = shared_ptr<DataChunk>(result->Fetch().release());
if (!chunk) {
result = nullptr;
}
}
}
QueryResultRow current_row;
shared_ptr<DataChunk> chunk;
QueryResult *result;
idx_t base_row;
public:
void Next() {
if (!chunk) {
return;
}
current_row.row++;
if (current_row.row >= chunk->size()) {
base_row += chunk->size();
chunk = result->Fetch();
current_row.row = 0;
if (!chunk || chunk->size() == 0) {
base_row = 0;
result = nullptr;
chunk.reset();
}
}
}
QueryResultIterator &operator++() {
Next();
return *this;
}
bool operator!=(const QueryResultIterator &other) const {
return result != other.result || base_row != other.base_row || current_row.row != other.current_row.row;
}
const QueryResultRow &operator*() const {
return current_row;
}
};
public:
DUCKDB_API QueryResultIterator begin() {
return QueryResultIterator(this);
}
DUCKDB_API QueryResultIterator end() {
return QueryResultIterator(nullptr);
}
protected:
DUCKDB_API string HeaderToString();
private:
QueryResult(const QueryResult &) = delete;
};
}
namespace duckdb {
class ClientContext;
class MaterializedQueryResult : public QueryResult {
public:
friend class ClientContext;
DUCKDB_API MaterializedQueryResult(StatementType statement_type, StatementProperties properties,
vector<string> names, unique_ptr<ColumnDataCollection> collection,
ClientProperties client_properties);
DUCKDB_API explicit MaterializedQueryResult(PreservedError error);
public:
DUCKDB_API unique_ptr<DataChunk> Fetch() override;
DUCKDB_API unique_ptr<DataChunk> FetchRaw() override;
DUCKDB_API string ToString() override;
DUCKDB_API string ToBox(ClientContext &context, const BoxRendererConfig &config) override;
DUCKDB_API Value GetValue(idx_t column, idx_t index);
template <class T>
T GetValue(idx_t column, idx_t index) {
auto value = GetValue(column, index);
return (T)value.GetValue<int64_t>();
}
DUCKDB_API idx_t RowCount() const;
ColumnDataCollection &Collection();
private:
unique_ptr<ColumnDataCollection> collection;
unique_ptr<ColumnDataRowCollection> row_collection;
ColumnDataScanState scan_state;
bool scan_initialized;
};
}
namespace duckdb {
enum class PendingExecutionResult : uint8_t { RESULT_READY, RESULT_NOT_READY, EXECUTION_ERROR };
}
#include <atomic>
namespace duckdb {
using std::atomic;
}
namespace duckdb {
enum class CatalogType : uint8_t {
INVALID = 0,
TABLE_ENTRY = 1,
SCHEMA_ENTRY = 2,
VIEW_ENTRY = 3,
INDEX_ENTRY = 4,
PREPARED_STATEMENT = 5,
SEQUENCE_ENTRY = 6,
COLLATION_ENTRY = 7,
TYPE_ENTRY = 8,
DATABASE_ENTRY = 9,
TABLE_FUNCTION_ENTRY = 25,
SCALAR_FUNCTION_ENTRY = 26,
AGGREGATE_FUNCTION_ENTRY = 27,
PRAGMA_FUNCTION_ENTRY = 28,
COPY_FUNCTION_ENTRY = 29,
MACRO_ENTRY = 30,
TABLE_MACRO_ENTRY = 31,
UPDATED_ENTRY = 50,
DELETED_ENTRY = 51,
};
DUCKDB_API string CatalogTypeToString(CatalogType type);
}
#include <memory>
namespace duckdb {
struct AlterInfo;
class Catalog;
class CatalogSet;
class ClientContext;
class CatalogEntry {
public:
CatalogEntry(CatalogType type, Catalog *catalog, string name);
virtual ~CatalogEntry();
idx_t oid;
CatalogType type;
Catalog *catalog;
CatalogSet *set;
string name;
bool deleted;
bool temporary;
bool internal;
atomic<transaction_t> timestamp;
unique_ptr<CatalogEntry> child;
CatalogEntry *parent;
public:
virtual unique_ptr<CatalogEntry> AlterEntry(ClientContext &context, AlterInfo *info);
virtual void UndoAlter(ClientContext &context, AlterInfo *info);
virtual unique_ptr<CatalogEntry> Copy(ClientContext &context);
virtual void SetAsRoot();
virtual string ToSQL();
virtual void Verify(Catalog &catalog);
};
}
namespace duckdb {
class SQLStatement;
class QueryErrorContext {
public:
explicit QueryErrorContext(SQLStatement *statement_ = nullptr, idx_t query_location_ = DConstants::INVALID_INDEX)
: statement(statement_), query_location(query_location_) {
}
SQLStatement *statement;
idx_t query_location;
public:
DUCKDB_API static string Format(const string &query, const string &error_message, int error_location);
DUCKDB_API string FormatErrorRecursive(const string &msg, vector<ExceptionFormatValue> &values);
template <class T, typename... Args>
string FormatErrorRecursive(const string &msg, vector<ExceptionFormatValue> &values, T param, Args... params) {
values.push_back(ExceptionFormatValue::CreateFormatValue<T>(param));
return FormatErrorRecursive(msg, values, params...);
}
template <typename... Args>
string FormatError(const string &msg, Args... params) {
vector<ExceptionFormatValue> values;
return FormatErrorRecursive(msg, values, params...);
}
};
}
namespace duckdb {
class Catalog;
class ClientContext;
class DatabaseInstance;
class Transaction;
struct CatalogTransaction {
CatalogTransaction(Catalog &catalog, ClientContext &context);
CatalogTransaction(DatabaseInstance &db, transaction_t transaction_id_p, transaction_t start_time_p);
DatabaseInstance *db;
ClientContext *context;
Transaction *transaction;
transaction_t transaction_id;
transaction_t start_time;
ClientContext &GetContext();
};
}
#include <functional>
namespace duckdb {
struct CreateSchemaInfo;
struct DropInfo;
struct BoundCreateTableInfo;
struct AlterTableInfo;
struct CreateTableFunctionInfo;
struct CreateCopyFunctionInfo;
struct CreatePragmaFunctionInfo;
struct CreateFunctionInfo;
struct CreateViewInfo;
struct CreateSequenceInfo;
struct CreateCollationInfo;
struct CreateIndexInfo;
struct CreateTypeInfo;
struct CreateTableInfo;
struct DatabaseSize;
class AttachedDatabase;
class ClientContext;
class Transaction;
class AggregateFunctionCatalogEntry;
class CollateCatalogEntry;
class SchemaCatalogEntry;
class TableCatalogEntry;
class ViewCatalogEntry;
class SequenceCatalogEntry;
class TableFunctionCatalogEntry;
class CopyFunctionCatalogEntry;
class PragmaFunctionCatalogEntry;
class CatalogSet;
class DatabaseInstance;
class DependencyManager;
struct CatalogLookup;
struct CatalogEntryLookup;
struct SimilarCatalogEntry;
class Binder;
class LogicalOperator;
class PhysicalOperator;
class LogicalCreateIndex;
class LogicalCreateTable;
class LogicalInsert;
class LogicalDelete;
class LogicalUpdate;
class CreateStatement;
class Catalog {
public:
explicit Catalog(AttachedDatabase &db);
virtual ~Catalog();
public:
DUCKDB_API static Catalog &GetSystemCatalog(ClientContext &context);
DUCKDB_API static Catalog &GetSystemCatalog(DatabaseInstance &db);
DUCKDB_API static Catalog &GetCatalog(ClientContext &context, const string &catalog_name);
DUCKDB_API static Catalog &GetCatalog(DatabaseInstance &db, const string &catalog_name);
DUCKDB_API static Catalog &GetCatalog(AttachedDatabase &db);
DUCKDB_API AttachedDatabase &GetAttached();
DUCKDB_API DatabaseInstance &GetDatabase();
virtual bool IsDuckCatalog() {
return false;
}
virtual void Initialize(bool load_builtin) = 0;
bool IsSystemCatalog() const;
bool IsTemporaryCatalog() const;
DUCKDB_API idx_t GetCatalogVersion();
DUCKDB_API idx_t ModifyCatalog();
DUCKDB_API const string &GetName();
DUCKDB_API idx_t GetOid();
DUCKDB_API virtual string GetCatalogType() = 0;
DUCKDB_API CatalogTransaction GetCatalogTransaction(ClientContext &context);
DUCKDB_API virtual CatalogEntry *CreateSchema(CatalogTransaction transaction, CreateSchemaInfo *info) = 0;
DUCKDB_API CatalogEntry *CreateSchema(ClientContext &context, CreateSchemaInfo *info);
DUCKDB_API CatalogEntry *CreateTable(CatalogTransaction transaction, BoundCreateTableInfo *info);
DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, BoundCreateTableInfo *info);
DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, unique_ptr<CreateTableInfo> info);
DUCKDB_API CatalogEntry *CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info);
DUCKDB_API CatalogEntry *CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo *info);
DUCKDB_API CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateFunction(CatalogTransaction transaction, CreateFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateView(CatalogTransaction transaction, CreateViewInfo *info);
DUCKDB_API CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info);
DUCKDB_API CatalogEntry *CreateSequence(CatalogTransaction transaction, CreateSequenceInfo *info);
DUCKDB_API CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info);
DUCKDB_API CatalogEntry *CreateType(CatalogTransaction transaction, CreateTypeInfo *info);
DUCKDB_API CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info);
DUCKDB_API CatalogEntry *CreateCollation(CatalogTransaction transaction, CreateCollationInfo *info);
DUCKDB_API CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info);
DUCKDB_API CatalogEntry *CreateIndex(CatalogTransaction transaction, CreateIndexInfo *info);
DUCKDB_API CatalogEntry *CreateIndex(ClientContext &context, CreateIndexInfo *info);
DUCKDB_API CatalogEntry *CreateTable(CatalogTransaction transaction, SchemaCatalogEntry *schema,
BoundCreateTableInfo *info);
DUCKDB_API CatalogEntry *CreateTableFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreateTableFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateCopyFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreateCopyFunctionInfo *info);
DUCKDB_API CatalogEntry *CreatePragmaFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreatePragmaFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreateFunctionInfo *info);
DUCKDB_API CatalogEntry *CreateView(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreateViewInfo *info);
DUCKDB_API CatalogEntry *CreateSequence(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreateSequenceInfo *info);
DUCKDB_API CatalogEntry *CreateType(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreateTypeInfo *info);
DUCKDB_API CatalogEntry *CreateCollation(CatalogTransaction transaction, SchemaCatalogEntry *schema,
CreateCollationInfo *info);
DUCKDB_API void DropEntry(ClientContext &context, DropInfo *info);
DUCKDB_API SchemaCatalogEntry *GetSchema(ClientContext &context, const string &name = DEFAULT_SCHEMA,
bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext());
DUCKDB_API virtual SchemaCatalogEntry *GetSchema(CatalogTransaction transaction, const string &schema_name,
bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext()) = 0;
DUCKDB_API static SchemaCatalogEntry *GetSchema(ClientContext &context, const string &catalog_name,
const string &schema_name, bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext());
DUCKDB_API virtual void ScanSchemas(ClientContext &context, std::function<void(CatalogEntry *)> callback) = 0;
DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &schema,
const string &name, bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext());
DUCKDB_API static CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &catalog,
const string &schema, const string &name, bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext());
DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, const string &schema, const string &name);
DUCKDB_API LogicalType GetType(ClientContext &context, const string &schema, const string &names, bool if_exists);
DUCKDB_API static LogicalType GetType(ClientContext &context, const string &catalog_name, const string &schema,
const string &name);
template <class T>
T *GetEntry(ClientContext &context, const string &schema_name, const string &name, bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext()) {
auto entry = GetEntry(context, T::Type, schema_name, name, if_exists, error_context);
if (entry && entry->type != T::Type) {
throw CatalogException(error_context.FormatError("%s is not an %s", name, T::Name));
}
return (T *)entry;
}
DUCKDB_API CatalogEntry *AddFunction(ClientContext &context, CreateFunctionInfo *info);
DUCKDB_API void Alter(ClientContext &context, AlterInfo *info);
virtual unique_ptr<PhysicalOperator> PlanCreateTableAs(ClientContext &context, LogicalCreateTable &op,
unique_ptr<PhysicalOperator> plan) = 0;
virtual unique_ptr<PhysicalOperator> PlanInsert(ClientContext &context, LogicalInsert &op,
unique_ptr<PhysicalOperator> plan) = 0;
virtual unique_ptr<PhysicalOperator> PlanDelete(ClientContext &context, LogicalDelete &op,
unique_ptr<PhysicalOperator> plan) = 0;
virtual unique_ptr<PhysicalOperator> PlanUpdate(ClientContext &context, LogicalUpdate &op,
unique_ptr<PhysicalOperator> plan) = 0;
virtual unique_ptr<LogicalOperator> BindCreateIndex(Binder &binder, CreateStatement &stmt, TableCatalogEntry &table,
unique_ptr<LogicalOperator> plan) = 0;
virtual DatabaseSize GetDatabaseSize(ClientContext &context) = 0;
virtual bool InMemory() = 0;
virtual string GetDBPath() = 0;
public:
template <class T>
static T *GetEntry(ClientContext &context, const string &catalog_name, const string &schema_name,
const string &name, bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext()) {
auto entry = GetEntry(context, T::Type, catalog_name, schema_name, name, if_exists, error_context);
if (entry && entry->type != T::Type) {
throw CatalogException(error_context.FormatError("%s is not an %s", name, T::Name));
}
return (T *)entry;
}
DUCKDB_API vector<SchemaCatalogEntry *> GetSchemas(ClientContext &context);
DUCKDB_API static vector<SchemaCatalogEntry *> GetSchemas(ClientContext &context, const string &catalog_name);
DUCKDB_API static vector<SchemaCatalogEntry *> GetAllSchemas(ClientContext &context);
virtual void Verify();
static CatalogException UnrecognizedConfigurationError(ClientContext &context, const string &name);
protected:
AttachedDatabase &db;
private:
CatalogEntryLookup LookupEntryInternal(CatalogTransaction transaction, CatalogType type, const string &schema,
const string &name);
CatalogEntryLookup LookupEntry(ClientContext &context, CatalogType type, const string &schema, const string &name,
bool if_exists = false, QueryErrorContext error_context = QueryErrorContext());
static CatalogEntryLookup LookupEntry(ClientContext &context, vector<CatalogLookup> &lookups, CatalogType type,
const string &name, bool if_exists = false,
QueryErrorContext error_context = QueryErrorContext());
static CatalogException CreateMissingEntryException(ClientContext &context, const string &entry_name,
CatalogType type,
const unordered_set<SchemaCatalogEntry *> &schemas,
QueryErrorContext error_context);
static SimilarCatalogEntry SimilarEntryInSchemas(ClientContext &context, const string &entry_name, CatalogType type,
const unordered_set<SchemaCatalogEntry *> &schemas);
virtual void DropSchema(ClientContext &context, DropInfo *info) = 0;
};
}
namespace duckdb {
enum class OperatorResultType : uint8_t { NEED_MORE_INPUT, HAVE_MORE_OUTPUT, FINISHED };
enum class OperatorFinalizeResultType : uint8_t { HAVE_MORE_OUTPUT, FINISHED };
enum class SinkResultType : uint8_t { NEED_MORE_INPUT, FINISHED };
enum class SinkFinalizeType : uint8_t { READY, NO_OUTPUT_POSSIBLE };
}
namespace duckdb {
enum class PhysicalOperatorType : uint8_t {
INVALID,
ORDER_BY,
LIMIT,
STREAMING_LIMIT,
LIMIT_PERCENT,
TOP_N,
WINDOW,
UNNEST,
UNGROUPED_AGGREGATE,
HASH_GROUP_BY,
PERFECT_HASH_GROUP_BY,
FILTER,
PROJECTION,
COPY_TO_FILE,
RESERVOIR_SAMPLE,
STREAMING_SAMPLE,
STREAMING_WINDOW,
TABLE_SCAN,
DUMMY_SCAN,
COLUMN_DATA_SCAN,
CHUNK_SCAN,
RECURSIVE_CTE_SCAN,
DELIM_SCAN,
EXPRESSION_SCAN,
POSITIONAL_SCAN,
BLOCKWISE_NL_JOIN,
NESTED_LOOP_JOIN,
HASH_JOIN,
CROSS_PRODUCT,
PIECEWISE_MERGE_JOIN,
IE_JOIN,
DELIM_JOIN,
INDEX_JOIN,
POSITIONAL_JOIN,
UNION,
RECURSIVE_CTE,
INSERT,
BATCH_INSERT,
DELETE_OPERATOR,
UPDATE,
CREATE_TABLE,
CREATE_TABLE_AS,
BATCH_CREATE_TABLE_AS,
CREATE_INDEX,
ALTER,
CREATE_SEQUENCE,
CREATE_VIEW,
CREATE_SCHEMA,
CREATE_MACRO,
DROP,
PRAGMA,
TRANSACTION,
CREATE_TYPE,
ATTACH,
DETACH,
EXPLAIN,
EXPLAIN_ANALYZE,
EMPTY_RESULT,
EXECUTE,
PREPARE,
VACUUM,
EXPORT,
SET,
LOAD,
INOUT_FUNCTION,
RESULT_COLLECTOR,
RESET,
EXTENSION
};
string PhysicalOperatorToString(PhysicalOperatorType type);
}
namespace duckdb {
class ClientContext;
class ThreadContext;
class Pipeline;
class ExecutionContext {
public:
ExecutionContext(ClientContext &client_p, ThreadContext &thread_p, Pipeline *pipeline_p)
: client(client_p), thread(thread_p), pipeline(pipeline_p) {
}
ClientContext &client;
ThreadContext &thread;
Pipeline *pipeline;
};
}
namespace duckdb {
class LogicalOperator;
struct SingleJoinRelation {
LogicalOperator *op;
LogicalOperator *parent;
SingleJoinRelation() {
}
SingleJoinRelation(LogicalOperator *op, LogicalOperator *parent) : op(op), parent(parent) {
}
};
struct JoinRelationSet {
JoinRelationSet(unique_ptr<idx_t[]> relations, idx_t count) : relations(std::move(relations)), count(count) {
}
string ToString() const;
unique_ptr<idx_t[]> relations;
idx_t count;
static bool IsSubset(JoinRelationSet *super, JoinRelationSet *sub);
};
class JoinRelationSetManager {
public:
struct JoinRelationTreeNode {
unique_ptr<JoinRelationSet> relation;
unordered_map<idx_t, unique_ptr<JoinRelationTreeNode>> children;
};
public:
JoinRelationSet *GetJoinRelation(idx_t index);
JoinRelationSet *GetJoinRelation(unordered_set<idx_t> &bindings);
JoinRelationSet *GetJoinRelation(unique_ptr<idx_t[]> relations, idx_t count);
JoinRelationSet *Union(JoinRelationSet *left, JoinRelationSet *right);
private:
JoinRelationTreeNode root;
};
}
namespace duckdb {
class Expression;
struct ExpressionHashFunction {
uint64_t operator()(const BaseExpression *const &expr) const {
return (uint64_t)expr->Hash();
}
};
struct ExpressionEquality {
bool operator()(const BaseExpression *const &a, const BaseExpression *const &b) const {
return a->Equals(b);
}
};
template <typename T>
using expression_map_t = unordered_map<BaseExpression *, T, ExpressionHashFunction, ExpressionEquality>;
using expression_set_t = unordered_set<BaseExpression *, ExpressionHashFunction, ExpressionEquality>;
}
namespace duckdb {
class BoundQueryNode;
class BoundSelectNode;
class BoundSetOperationNode;
class BoundRecursiveCTENode;
class Expression;
class BoundAggregateExpression;
class BoundBetweenExpression;
class BoundCaseExpression;
class BoundCastExpression;
class BoundColumnRefExpression;
class BoundComparisonExpression;
class BoundConjunctionExpression;
class BoundConstantExpression;
class BoundDefaultExpression;
class BoundFunctionExpression;
class BoundOperatorExpression;
class BoundParameterExpression;
class BoundReferenceExpression;
class BoundSubqueryExpression;
class BoundUnnestExpression;
class BoundWindowExpression;
class BoundTableRef;
class BoundBaseTableRef;
class BoundJoinRef;
class BoundSubqueryRef;
class BoundTableFunction;
class BoundEmptyTableRef;
class BoundExpressionListRef;
class BoundCTERef;
}
namespace duckdb {
class LogicalOperator;
class LogicalAggregate;
class LogicalAnyJoin;
class LogicalColumnDataGet;
class LogicalComparisonJoin;
class LogicalCopyToFile;
class LogicalCreate;
class LogicalCreateTable;
class LogicalCreateIndex;
class LogicalCreateTable;
class LogicalCrossProduct;
class LogicalCTERef;
class LogicalDelete;
class LogicalDelimGet;
class LogicalDelimJoin;
class LogicalDistinct;
class LogicalDummyScan;
class LogicalEmptyResult;
class LogicalExecute;
class LogicalExplain;
class LogicalExport;
class LogicalExpressionGet;
class LogicalFilter;
class LogicalGet;
class LogicalInsert;
class LogicalJoin;
class LogicalLimit;
class LogicalOrder;
class LogicalPositionalJoin;
class LogicalPragma;
class LogicalPrepare;
class LogicalProjection;
class LogicalRecursiveCTE;
class LogicalSetOperation;
class LogicalSample;
class LogicalShow;
class LogicalSimple;
class LogicalSet;
class LogicalReset;
class LogicalTopN;
class LogicalUnnest;
class LogicalUpdate;
class LogicalWindow;
}
#include <functional>
namespace duckdb {
class LogicalOperatorVisitor {
public:
virtual ~LogicalOperatorVisitor() {};
virtual void VisitOperator(LogicalOperator &op);
virtual void VisitExpression(unique_ptr<Expression> *expression);
static void EnumerateExpressions(LogicalOperator &op,
const std::function<void(unique_ptr<Expression> *child)> &callback);
protected:
void VisitOperatorChildren(LogicalOperator &op);
void VisitOperatorExpressions(LogicalOperator &op);
virtual void VisitExpressionChildren(Expression &expression);
virtual unique_ptr<Expression> VisitReplace(BoundAggregateExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundBetweenExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundCaseExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundCastExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundComparisonExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundConjunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundConstantExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundDefaultExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundFunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundOperatorExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundReferenceExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundSubqueryExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundParameterExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundWindowExpression &expr, unique_ptr<Expression> *expr_ptr);
virtual unique_ptr<Expression> VisitReplace(BoundUnnestExpression &expr, unique_ptr<Expression> *expr_ptr);
};
}
#include <stdint.h>
#include <string.h>
namespace duckdb_hll {
#define HLL_C_OK 0
#define HLL_C_ERR -1
typedef struct {
void *ptr;
} robj;
robj *hll_create(void);
int hllSparseToDense(robj *o);
void hll_destroy(robj *obj);
int hll_add(robj *o, unsigned char *ele, size_t elesize);
int hll_count(robj *o, size_t *result);
robj *hll_merge(robj **hlls, size_t hll_count);
uint64_t get_size();
uint64_t MurmurHash64A(const void *key, int len, unsigned int seed);
}
namespace duckdb {
void AddToLogsInternal(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], void ***logs[],
const SelectionVector *log_sel);
void AddToSingleLogInternal(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], void *log);
}
namespace duckdb {
enum class HLLStorageType { UNCOMPRESSED = 1 };
class FieldWriter;
class FieldReader;
class HyperLogLog {
public:
HyperLogLog();
~HyperLogLog();
HyperLogLog(const HyperLogLog &) = delete;
void Add(data_ptr_t element, idx_t size);
idx_t Count() const;
unique_ptr<HyperLogLog> Merge(HyperLogLog &other);
HyperLogLog *MergePointer(HyperLogLog &other);
static unique_ptr<HyperLogLog> Merge(HyperLogLog logs[], idx_t count);
static idx_t GetSize();
data_ptr_t GetPtr() const;
unique_ptr<HyperLogLog> Copy();
void Serialize(FieldWriter &writer) const;
static unique_ptr<HyperLogLog> Deserialize(FieldReader &reader);
public:
static void ProcessEntries(UnifiedVectorFormat &vdata, const LogicalType &type, uint64_t hashes[], uint8_t counts[],
idx_t count);
static void AddToLogs(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[],
HyperLogLog **logs[], const SelectionVector *log_sel);
void AddToLog(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[]);
private:
explicit HyperLogLog(void *hll);
void *hll;
mutex lock;
};
}
namespace duckdb {
class Serializer;
class Deserializer;
class Vector;
class DistinctStatistics : public BaseStatistics {
public:
DistinctStatistics();
explicit DistinctStatistics(unique_ptr<HyperLogLog> log, idx_t sample_count, idx_t total_count);
unique_ptr<HyperLogLog> log;
atomic<idx_t> sample_count;
atomic<idx_t> total_count;
public:
void Merge(const BaseStatistics &other) override;
unique_ptr<BaseStatistics> Copy() const override;
void Serialize(Serializer &serializer) const override;
void Serialize(FieldWriter &writer) const override;
static unique_ptr<DistinctStatistics> Deserialize(Deserializer &source);
static unique_ptr<DistinctStatistics> Deserialize(FieldReader &reader);
void Update(Vector &update, idx_t count, bool sample = true);
void Update(UnifiedVectorFormat &update_data, const LogicalType &ptype, idx_t count, bool sample = true);
string ToString() const override;
idx_t GetCount() const;
private:
static constexpr const double SAMPLE_RATE = 0.1;
};
}
namespace duckdb {
enum class FilterPropagateResult : uint8_t {
NO_PRUNING_POSSIBLE = 0,
FILTER_ALWAYS_TRUE = 1,
FILTER_ALWAYS_FALSE = 2,
FILTER_TRUE_OR_NULL = 3,
FILTER_FALSE_OR_NULL = 4
};
}
namespace duckdb {
class BaseStatistics;
class FieldWriter;
class FieldReader;
enum class TableFilterType : uint8_t {
CONSTANT_COMPARISON = 0, IS_NULL = 1,
IS_NOT_NULL = 2,
CONJUNCTION_OR = 3,
CONJUNCTION_AND = 4
};
class TableFilter {
public:
TableFilter(TableFilterType filter_type_p) : filter_type(filter_type_p) {
}
virtual ~TableFilter() {
}
TableFilterType filter_type;
public:
virtual FilterPropagateResult CheckStatistics(BaseStatistics &stats) = 0;
virtual string ToString(const string &column_name) = 0;
virtual bool Equals(const TableFilter &other) const {
return filter_type != other.filter_type;
}
void Serialize(Serializer &serializer) const;
virtual void Serialize(FieldWriter &writer) const = 0;
static unique_ptr<TableFilter> Deserialize(Deserializer &source);
};
class TableFilterSet {
public:
unordered_map<idx_t, unique_ptr<TableFilter>> filters;
public:
void PushFilter(idx_t table_index, unique_ptr<TableFilter> filter);
bool Equals(TableFilterSet &other) {
if (filters.size() != other.filters.size()) {
return false;
}
for (auto &entry : filters) {
auto other_entry = other.filters.find(entry.first);
if (other_entry == other.filters.end()) {
return false;
}
if (!entry.second->Equals(*other_entry->second)) {
return false;
}
}
return true;
}
static bool Equals(TableFilterSet *left, TableFilterSet *right) {
if (left == right) {
return true;
}
if (!left || !right) {
return false;
}
return left->Equals(*right);
}
void Serialize(Serializer &serializer) const;
static unique_ptr<TableFilterSet> Deserialize(Deserializer &source);
};
}
namespace duckdb {
class EstimatedProperties {
public:
EstimatedProperties(double cardinality, double cost) : cardinality(cardinality), cost(cost) {};
EstimatedProperties() : cardinality(0), cost(0) {};
template <class T>
T GetCardinality() const {
throw NotImplementedException("Unsupported type for GetCardinality");
}
double GetCost() const;
void SetCost(double new_cost);
void SetCardinality(double cardinality);
private:
double cardinality;
double cost;
public:
unique_ptr<EstimatedProperties> Copy();
};
template <>
double EstimatedProperties::GetCardinality() const;
template <>
idx_t EstimatedProperties::GetCardinality() const;
}
#include <functional>
namespace duckdb {
struct ColumnBinding {
idx_t table_index;
idx_t column_index;
ColumnBinding() : table_index(DConstants::INVALID_INDEX), column_index(DConstants::INVALID_INDEX) {
}
ColumnBinding(idx_t table, idx_t column) : table_index(table), column_index(column) {
}
bool operator==(const ColumnBinding &rhs) const {
return table_index == rhs.table_index && column_index == rhs.column_index;
}
};
}
#include <functional>
namespace duckdb {
class Expression;
class LogicalOperator;
struct FilterInfo {
idx_t filter_index;
JoinRelationSet *left_set = nullptr;
JoinRelationSet *right_set = nullptr;
ColumnBinding left_binding;
ColumnBinding right_binding;
JoinRelationSet *set = nullptr;
};
struct FilterNode {
vector<FilterInfo *> filters;
unordered_map<idx_t, unique_ptr<FilterNode>> children;
};
struct NeighborInfo {
JoinRelationSet *neighbor;
vector<FilterInfo *> filters;
};
class QueryGraph {
public:
struct QueryEdge {
vector<unique_ptr<NeighborInfo>> neighbors;
unordered_map<idx_t, unique_ptr<QueryEdge>> children;
};
public:
string ToString() const;
void Print();
void CreateEdge(JoinRelationSet *left, JoinRelationSet *right, FilterInfo *info);
vector<NeighborInfo *> GetConnections(JoinRelationSet *node, JoinRelationSet *other);
vector<idx_t> GetNeighbors(JoinRelationSet *node, unordered_set<idx_t> &exclusion_set);
void EnumerateNeighbors(JoinRelationSet *node, const std::function<bool(NeighborInfo *)> &callback);
private:
QueryEdge *GetQueryEdge(JoinRelationSet *left);
QueryEdge root;
};
}
namespace duckdb {
class JoinOrderOptimizer;
class JoinNode {
public:
JoinRelationSet *set;
NeighborInfo *info;
bool has_filter;
JoinNode *left;
JoinNode *right;
unique_ptr<EstimatedProperties> estimated_props;
JoinNode(JoinRelationSet *set, const double base_cardinality);
JoinNode(JoinRelationSet *set, NeighborInfo *info, JoinNode *left, JoinNode *right, const double base_cardinality,
double cost);
bool operator==(const JoinNode &other) {
return other.set->ToString().compare(set->ToString()) == 0;
}
private:
double base_cardinality;
public:
template <class CARDINALITY_TYPE>
CARDINALITY_TYPE GetCardinality() const {
return estimated_props->GetCardinality<CARDINALITY_TYPE>();
}
double GetCost();
void SetCost(double cost);
double GetBaseTableCardinality();
void SetBaseTableCardinality(double base_card);
void SetEstimatedCardinality(double estimated_card);
void PrintJoinNode();
string ToString();
};
}
namespace duckdb {
class Event;
class Executor;
class PhysicalOperator;
class Pipeline;
class PipelineBuildState;
class MetaPipeline;
class OperatorState {
public:
virtual ~OperatorState() {
}
virtual void Finalize(PhysicalOperator *op, ExecutionContext &context) {
}
};
class GlobalOperatorState {
public:
virtual ~GlobalOperatorState() {
}
};
class GlobalSinkState {
public:
GlobalSinkState() : state(SinkFinalizeType::READY) {
}
virtual ~GlobalSinkState() {
}
SinkFinalizeType state;
};
class LocalSinkState {
public:
virtual ~LocalSinkState() {
}
idx_t batch_index = DConstants::INVALID_INDEX;
};
class GlobalSourceState {
public:
virtual ~GlobalSourceState() {
}
virtual idx_t MaxThreads() {
return 1;
}
};
class LocalSourceState {
public:
virtual ~LocalSourceState() {
}
};
class PhysicalOperator {
public:
PhysicalOperator(PhysicalOperatorType type, vector<LogicalType> types, idx_t estimated_cardinality)
: type(type), types(std::move(types)), estimated_cardinality(estimated_cardinality) {
estimated_props = make_unique<EstimatedProperties>(estimated_cardinality, 0);
}
virtual ~PhysicalOperator() {
}
PhysicalOperatorType type;
vector<unique_ptr<PhysicalOperator>> children;
vector<LogicalType> types;
idx_t estimated_cardinality;
unique_ptr<EstimatedProperties> estimated_props;
unique_ptr<GlobalSinkState> sink_state;
unique_ptr<GlobalOperatorState> op_state;
mutex lock;
public:
virtual string GetName() const;
virtual string ParamsToString() const {
return "";
}
virtual string ToString() const;
void Print() const;
virtual vector<PhysicalOperator *> GetChildren() const;
const vector<LogicalType> &GetTypes() const {
return types;
}
virtual bool Equals(const PhysicalOperator &other) const {
return false;
}
virtual void Verify();
virtual bool IsOrderDependent() const {
return false;
}
public:
virtual unique_ptr<OperatorState> GetOperatorState(ExecutionContext &context) const;
virtual unique_ptr<GlobalOperatorState> GetGlobalOperatorState(ClientContext &context) const;
virtual OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk,
GlobalOperatorState &gstate, OperatorState &state) const;
virtual OperatorFinalizeResultType FinalExecute(ExecutionContext &context, DataChunk &chunk,
GlobalOperatorState &gstate, OperatorState &state) const;
virtual bool ParallelOperator() const {
return false;
}
virtual bool RequiresFinalExecute() const {
return false;
}
public:
virtual unique_ptr<LocalSourceState> GetLocalSourceState(ExecutionContext &context,
GlobalSourceState &gstate) const;
virtual unique_ptr<GlobalSourceState> GetGlobalSourceState(ClientContext &context) const;
virtual void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
LocalSourceState &lstate) const;
virtual idx_t GetBatchIndex(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
LocalSourceState &lstate) const;
virtual bool IsSource() const {
return false;
}
virtual bool ParallelSource() const {
return false;
}
virtual bool SupportsBatchIndex() const {
return false;
}
virtual bool IsOrderPreserving() const {
return true;
}
virtual double GetProgress(ClientContext &context, GlobalSourceState &gstate) const;
public:
virtual SinkResultType Sink(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate,
DataChunk &input) const;
virtual void Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const;
virtual SinkFinalizeType Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
GlobalSinkState &gstate) const;
virtual unique_ptr<LocalSinkState> GetLocalSinkState(ExecutionContext &context) const;
virtual unique_ptr<GlobalSinkState> GetGlobalSinkState(ClientContext &context) const;
static idx_t GetMaxThreadMemory(ClientContext &context);
virtual bool IsSink() const {
return false;
}
virtual bool ParallelSink() const {
return false;
}
virtual bool RequiresBatchIndex() const {
return false;
}
public:
virtual vector<const PhysicalOperator *> GetSources() const;
bool AllSourcesSupportBatchIndex() const;
virtual bool AllOperatorsPreserveOrder() const;
virtual void BuildPipelines(Pipeline ¤t, MetaPipeline &meta_pipeline);
};
class CachingOperatorState : public OperatorState {
public:
~CachingOperatorState() override {
}
virtual void Finalize(PhysicalOperator *op, ExecutionContext &context) override {
}
unique_ptr<DataChunk> cached_chunk;
bool initialized = false;
bool can_cache_chunk = false;
};
class CachingPhysicalOperator : public PhysicalOperator {
public:
static constexpr const idx_t CACHE_THRESHOLD = 64;
CachingPhysicalOperator(PhysicalOperatorType type, vector<LogicalType> types, idx_t estimated_cardinality);
bool caching_supported;
public:
OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk,
GlobalOperatorState &gstate, OperatorState &state) const final;
OperatorFinalizeResultType FinalExecute(ExecutionContext &context, DataChunk &chunk, GlobalOperatorState &gstate,
OperatorState &state) const final;
bool RequiresFinalExecute() const final {
return caching_supported;
}
protected:
virtual OperatorResultType ExecuteInternal(ExecutionContext &context, DataChunk &input, DataChunk &chunk,
GlobalOperatorState &gstate, OperatorState &state) const = 0;
private:
bool CanCacheType(const LogicalType &type);
};
}
#include <functional>
namespace duckdb {
class BaseStatistics;
class DependencyList;
class LogicalGet;
class TableFilterSet;
struct TableFunctionInfo {
DUCKDB_API virtual ~TableFunctionInfo();
};
struct GlobalTableFunctionState {
public:
constexpr static const int64_t MAX_THREADS = 999999999;
public:
DUCKDB_API virtual ~GlobalTableFunctionState();
DUCKDB_API virtual idx_t MaxThreads() const {
return 1;
}
};
struct LocalTableFunctionState {
DUCKDB_API virtual ~LocalTableFunctionState();
};
struct TableFunctionBindInput {
TableFunctionBindInput(vector<Value> &inputs, named_parameter_map_t &named_parameters,
vector<LogicalType> &input_table_types, vector<string> &input_table_names,
TableFunctionInfo *info)
: inputs(inputs), named_parameters(named_parameters), input_table_types(input_table_types),
input_table_names(input_table_names), info(info) {
}
vector<Value> &inputs;
named_parameter_map_t &named_parameters;
vector<LogicalType> &input_table_types;
vector<string> &input_table_names;
TableFunctionInfo *info;
};
struct TableFunctionInitInput {
TableFunctionInitInput(const FunctionData *bind_data_p, const vector<column_t> &column_ids_p,
const vector<idx_t> &projection_ids_p, TableFilterSet *filters_p)
: bind_data(bind_data_p), column_ids(column_ids_p), projection_ids(projection_ids_p), filters(filters_p) {
}
const FunctionData *bind_data;
const vector<column_t> &column_ids;
const vector<idx_t> projection_ids;
TableFilterSet *filters;
bool CanRemoveFilterColumns() const {
if (projection_ids.empty()) {
return false;
} else if (projection_ids.size() == column_ids.size()) {
return false;
} else {
return true;
}
}
};
struct TableFunctionInput {
public:
TableFunctionInput(const FunctionData *bind_data_p, LocalTableFunctionState *local_state_p,
GlobalTableFunctionState *global_state_p)
: bind_data(bind_data_p), local_state(local_state_p), global_state(global_state_p) {
}
public:
const FunctionData *bind_data;
LocalTableFunctionState *local_state;
GlobalTableFunctionState *global_state;
};
enum ScanType { TABLE, PARQUET };
struct BindInfo {
public:
explicit BindInfo(ScanType type_p) : type(type_p) {};
unordered_map<string, Value> options;
ScanType type;
void InsertOption(string name, Value value) {
if (options.find(name) != options.end()) {
throw InternalException("This option already exists");
}
options[name] = value;
}
template <class T>
T GetOption(string name) {
if (options.find(name) == options.end()) {
throw InternalException("This option does not exist");
}
return options[name].GetValue<T>();
}
template <class T>
vector<T> GetOptionList(string name) {
if (options.find(name) == options.end()) {
throw InternalException("This option does not exist");
}
auto option = options[name];
if (option.type().id() != LogicalTypeId::LIST) {
throw InternalException("This option is not a list");
}
vector<T> result;
auto list_children = ListValue::GetChildren(option);
for (auto &child : list_children) {
result.emplace_back(child.GetValue<T>());
}
return result;
}
};
typedef unique_ptr<FunctionData> (*table_function_bind_t)(ClientContext &context, TableFunctionBindInput &input,
vector<LogicalType> &return_types, vector<string> &names);
typedef unique_ptr<GlobalTableFunctionState> (*table_function_init_global_t)(ClientContext &context,
TableFunctionInitInput &input);
typedef unique_ptr<LocalTableFunctionState> (*table_function_init_local_t)(ExecutionContext &context,
TableFunctionInitInput &input,
GlobalTableFunctionState *global_state);
typedef unique_ptr<BaseStatistics> (*table_statistics_t)(ClientContext &context, const FunctionData *bind_data,
column_t column_index);
typedef void (*table_function_t)(ClientContext &context, TableFunctionInput &data, DataChunk &output);
typedef OperatorResultType (*table_in_out_function_t)(ExecutionContext &context, TableFunctionInput &data,
DataChunk &input, DataChunk &output);
typedef OperatorFinalizeResultType (*table_in_out_function_final_t)(ExecutionContext &context, TableFunctionInput &data,
DataChunk &output);
typedef idx_t (*table_function_get_batch_index_t)(ClientContext &context, const FunctionData *bind_data,
LocalTableFunctionState *local_state,
GlobalTableFunctionState *global_state);
typedef BindInfo (*table_function_get_bind_info)(const FunctionData *bind_data);
typedef double (*table_function_progress_t)(ClientContext &context, const FunctionData *bind_data,
const GlobalTableFunctionState *global_state);
typedef void (*table_function_dependency_t)(DependencyList &dependencies, const FunctionData *bind_data);
typedef unique_ptr<NodeStatistics> (*table_function_cardinality_t)(ClientContext &context,
const FunctionData *bind_data);
typedef void (*table_function_pushdown_complex_filter_t)(ClientContext &context, LogicalGet &get,
FunctionData *bind_data,
vector<unique_ptr<Expression>> &filters);
typedef string (*table_function_to_string_t)(const FunctionData *bind_data);
typedef void (*table_function_serialize_t)(FieldWriter &writer, const FunctionData *bind_data,
const TableFunction &function);
typedef unique_ptr<FunctionData> (*table_function_deserialize_t)(ClientContext &context, FieldReader &reader,
TableFunction &function);
class TableFunction : public SimpleNamedParameterFunction {
public:
DUCKDB_API
TableFunction(string name, vector<LogicalType> arguments, table_function_t function,
table_function_bind_t bind = nullptr, table_function_init_global_t init_global = nullptr,
table_function_init_local_t init_local = nullptr);
DUCKDB_API
TableFunction(const vector<LogicalType> &arguments, table_function_t function, table_function_bind_t bind = nullptr,
table_function_init_global_t init_global = nullptr, table_function_init_local_t init_local = nullptr);
DUCKDB_API TableFunction();
table_function_bind_t bind;
table_function_init_global_t init_global;
table_function_init_local_t init_local;
table_function_t function;
table_in_out_function_t in_out_function;
table_in_out_function_final_t in_out_function_final;
table_statistics_t statistics;
table_function_dependency_t dependency;
table_function_cardinality_t cardinality;
table_function_pushdown_complex_filter_t pushdown_complex_filter;
table_function_to_string_t to_string;
table_function_progress_t table_scan_progress;
table_function_get_batch_index_t get_batch_index;
table_function_get_bind_info get_batch_info;
table_function_serialize_t serialize;
table_function_deserialize_t deserialize;
bool projection_pushdown;
bool filter_pushdown;
bool filter_prune;
shared_ptr<TableFunctionInfo> function_info;
};
}
namespace duckdb {
class ClientContext;
class Executor;
enum class TaskExecutionMode : uint8_t { PROCESS_ALL, PROCESS_PARTIAL };
enum class TaskExecutionResult : uint8_t { TASK_FINISHED, TASK_NOT_FINISHED, TASK_ERROR };
class Task {
public:
virtual ~Task() {
}
virtual TaskExecutionResult Execute(TaskExecutionMode mode) = 0;
};
class ExecutorTask : public Task {
public:
ExecutorTask(Executor &executor);
ExecutorTask(ClientContext &context);
virtual ~ExecutorTask();
Executor &executor;
public:
virtual TaskExecutionResult ExecuteTask(TaskExecutionMode mode) = 0;
TaskExecutionResult Execute(TaskExecutionMode mode) override;
};
}
namespace duckdb {
struct ConcurrentQueue;
struct QueueProducerToken;
class ClientContext;
class DatabaseInstance;
class TaskScheduler;
struct SchedulerThread;
struct ProducerToken {
ProducerToken(TaskScheduler &scheduler, unique_ptr<QueueProducerToken> token);
~ProducerToken();
TaskScheduler &scheduler;
unique_ptr<QueueProducerToken> token;
mutex producer_lock;
};
class TaskScheduler {
constexpr static int64_t TASK_TIMEOUT_USECS = 5000;
public:
TaskScheduler(DatabaseInstance &db);
~TaskScheduler();
DUCKDB_API static TaskScheduler &GetScheduler(ClientContext &context);
DUCKDB_API static TaskScheduler &GetScheduler(DatabaseInstance &db);
unique_ptr<ProducerToken> CreateProducer();
void ScheduleTask(ProducerToken &producer, unique_ptr<Task> task);
bool GetTaskFromProducer(ProducerToken &token, unique_ptr<Task> &task);
void ExecuteForever(atomic<bool> *marker);
idx_t ExecuteTasks(atomic<bool> *marker, idx_t max_tasks);
void ExecuteTasks(idx_t max_tasks);
void SetThreads(int32_t n);
DUCKDB_API int32_t NumberOfThreads();
void Signal(idx_t n);
private:
void SetThreadsInternal(int32_t n);
private:
DatabaseInstance &db;
unique_ptr<ConcurrentQueue> queue;
mutex thread_lock;
vector<unique_ptr<SchedulerThread>> threads;
vector<unique_ptr<atomic<bool>>> markers;
};
}
namespace duckdb {
class Executor;
class Event;
class MetaPipeline;
class PipelineBuildState {
public:
constexpr static idx_t BATCH_INCREMENT = 10000000000000;
public:
unordered_map<PhysicalOperator *, Pipeline *> delim_join_dependencies;
public:
void SetPipelineSource(Pipeline &pipeline, PhysicalOperator *op);
void SetPipelineSink(Pipeline &pipeline, PhysicalOperator *op, idx_t sink_pipeline_count);
void SetPipelineOperators(Pipeline &pipeline, vector<PhysicalOperator *> operators);
void AddPipelineOperator(Pipeline &pipeline, PhysicalOperator *op);
shared_ptr<Pipeline> CreateChildPipeline(Executor &executor, Pipeline &pipeline, PhysicalOperator *op);
PhysicalOperator *GetPipelineSource(Pipeline &pipeline);
PhysicalOperator *GetPipelineSink(Pipeline &pipeline);
vector<PhysicalOperator *> GetPipelineOperators(Pipeline &pipeline);
};
class Pipeline : public std::enable_shared_from_this<Pipeline> {
friend class Executor;
friend class PipelineExecutor;
friend class PipelineEvent;
friend class PipelineFinishEvent;
friend class PipelineBuildState;
friend class MetaPipeline;
public:
explicit Pipeline(Executor &execution_context);
Executor &executor;
public:
ClientContext &GetClientContext();
void AddDependency(shared_ptr<Pipeline> &pipeline);
void Ready();
void Reset();
void ResetSink();
void ResetSource(bool force);
void ClearSource() {
source_state.reset();
}
void Schedule(shared_ptr<Event> &event);
void Finalize(Event &event);
string ToString() const;
void Print() const;
void PrintDependencies() const;
bool GetProgress(double ¤t_percentage, idx_t &estimated_cardinality);
vector<PhysicalOperator *> GetOperators() const;
PhysicalOperator *GetSink() {
return sink;
}
PhysicalOperator *GetSource() {
return source;
}
bool IsOrderDependent() const;
private:
bool ready;
atomic<bool> initialized;
PhysicalOperator *source = nullptr;
vector<PhysicalOperator *> operators;
PhysicalOperator *sink = nullptr;
unique_ptr<GlobalSourceState> source_state;
vector<weak_ptr<Pipeline>> parents;
vector<weak_ptr<Pipeline>> dependencies;
idx_t base_batch_index = 0;
private:
void ScheduleSequentialTask(shared_ptr<Event> &event);
bool LaunchScanTasks(shared_ptr<Event> &event, idx_t max_threads);
bool ScheduleParallel(shared_ptr<Event> &event);
};
}
namespace duckdb {
class ClientContext;
class DataChunk;
class PhysicalOperator;
class PipelineExecutor;
class OperatorState;
class QueryProfiler;
class ThreadContext;
class Task;
struct PipelineEventStack;
struct ProducerToken;
struct ScheduleEventData;
class Executor {
friend class Pipeline;
friend class PipelineTask;
friend class PipelineBuildState;
public:
explicit Executor(ClientContext &context);
~Executor();
ClientContext &context;
public:
static Executor &Get(ClientContext &context);
void Initialize(PhysicalOperator *physical_plan);
void Initialize(unique_ptr<PhysicalOperator> physical_plan);
void CancelTasks();
PendingExecutionResult ExecuteTask();
void Reset();
vector<LogicalType> GetTypes();
unique_ptr<DataChunk> FetchChunk();
void PushError(PreservedError exception);
bool HasError();
void ThrowException();
void WorkOnTasks();
void Flush(ThreadContext &context);
bool GetPipelinesProgress(double ¤t_progress);
void CompletePipeline() {
completed_pipelines++;
}
ProducerToken &GetToken() {
return *producer;
}
void AddEvent(shared_ptr<Event> event);
void AddRecursiveCTE(PhysicalOperator *rec_cte);
void ReschedulePipelines(const vector<shared_ptr<MetaPipeline>> &pipelines, vector<shared_ptr<Event>> &events);
bool HasResultCollector();
unique_ptr<QueryResult> GetResult();
bool ExecutionIsFinished();
private:
void InitializeInternal(PhysicalOperator *physical_plan);
void ScheduleEvents(const vector<shared_ptr<MetaPipeline>> &meta_pipelines);
static void ScheduleEventsInternal(ScheduleEventData &event_data);
static void VerifyScheduledEvents(const ScheduleEventData &event_data);
static void VerifyScheduledEventsInternal(const idx_t i, const vector<Event *> &vertices, vector<bool> &visited,
vector<bool> &recursion_stack);
static void SchedulePipeline(const shared_ptr<MetaPipeline> &pipeline, ScheduleEventData &event_data);
bool NextExecutor();
shared_ptr<Pipeline> CreateChildPipeline(Pipeline *current, PhysicalOperator *op);
void VerifyPipeline(Pipeline &pipeline);
void VerifyPipelines();
private:
PhysicalOperator *physical_plan;
unique_ptr<PhysicalOperator> owned_plan;
mutex executor_lock;
mutex error_lock;
vector<shared_ptr<Pipeline>> pipelines;
vector<shared_ptr<Pipeline>> root_pipelines;
vector<PhysicalOperator *> recursive_ctes;
unique_ptr<PipelineExecutor> root_executor;
idx_t root_pipeline_idx;
unique_ptr<ProducerToken> producer;
vector<PreservedError> exceptions;
vector<shared_ptr<Event>> events;
shared_ptr<QueryProfiler> profiler;
atomic<idx_t> completed_pipelines;
idx_t total_pipelines;
bool cancelled;
PendingExecutionResult execution_result;
unique_ptr<Task> task;
};
}
namespace duckdb {
class ClientContext;
class ClientContextLock;
class PreparedStatementData;
class PendingQueryResult : public BaseQueryResult {
friend class ClientContext;
public:
DUCKDB_API PendingQueryResult(shared_ptr<ClientContext> context, PreparedStatementData &statement,
vector<LogicalType> types, bool allow_stream_result);
DUCKDB_API explicit PendingQueryResult(PreservedError error_message);
DUCKDB_API ~PendingQueryResult();
public:
DUCKDB_API PendingExecutionResult ExecuteTask();
DUCKDB_API unique_ptr<QueryResult> Execute();
DUCKDB_API void Close();
private:
shared_ptr<ClientContext> context;
bool allow_stream_result;
private:
void CheckExecutableInternal(ClientContextLock &lock);
PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock);
unique_ptr<QueryResult> ExecuteInternal(ClientContextLock &lock);
unique_ptr<ClientContextLock> LockContext();
};
}
namespace duckdb {
class ClientContext;
class PreparedStatementData;
class PreparedStatement {
public:
DUCKDB_API PreparedStatement(shared_ptr<ClientContext> context, shared_ptr<PreparedStatementData> data,
string query, idx_t n_param, case_insensitive_map_t<idx_t> named_param_map);
DUCKDB_API explicit PreparedStatement(PreservedError error);
DUCKDB_API ~PreparedStatement();
public:
shared_ptr<ClientContext> context;
shared_ptr<PreparedStatementData> data;
string query;
bool success;
PreservedError error;
idx_t n_param;
case_insensitive_map_t<idx_t> named_param_map;
public:
DUCKDB_API const string &GetError();
DUCKDB_API bool HasError() const;
DUCKDB_API idx_t ColumnCount();
DUCKDB_API StatementType GetStatementType();
DUCKDB_API StatementProperties GetStatementProperties();
DUCKDB_API const vector<LogicalType> &GetTypes();
DUCKDB_API const vector<string> &GetNames();
DUCKDB_API vector<LogicalType> GetExpectedParameterTypes() const;
template <typename... Args>
unique_ptr<PendingQueryResult> PendingQuery(Args... args) {
vector<Value> values;
return PendingQueryRecursive(values, args...);
}
template <typename... Args>
unique_ptr<QueryResult> Execute(Args... args) {
vector<Value> values;
return ExecuteRecursive(values, args...);
}
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(vector<Value> &values, bool allow_stream_result = true);
DUCKDB_API unique_ptr<QueryResult> Execute(vector<Value> &values, bool allow_stream_result = true);
private:
unique_ptr<PendingQueryResult> PendingQueryRecursive(vector<Value> &values) {
return PendingQuery(values);
}
template <typename T, typename... Args>
unique_ptr<PendingQueryResult> PendingQueryRecursive(vector<Value> &values, T value, Args... args) {
values.push_back(Value::CreateValue<T>(value));
return PendingQueryRecursive(values, args...);
}
unique_ptr<QueryResult> ExecuteRecursive(vector<Value> &values) {
return Execute(values);
}
template <typename T, typename... Args>
unique_ptr<QueryResult> ExecuteRecursive(vector<Value> &values, T value, Args... args) {
values.push_back(Value::CreateValue<T>(value));
return ExecuteRecursive(values, args...);
}
};
}
namespace duckdb {
enum class JoinType : uint8_t {
INVALID = 0, LEFT = 1, RIGHT = 2, INNER = 3, OUTER = 4, SEMI = 5, ANTI = 6, MARK = 7, SINGLE = 8 };
DUCKDB_API string JoinTypeToString(JoinType type);
bool IsLeftOuterJoin(JoinType type);
bool IsRightOuterJoin(JoinType type);
}
namespace duckdb {
enum class RelationType : uint8_t {
INVALID_RELATION,
TABLE_RELATION,
PROJECTION_RELATION,
FILTER_RELATION,
EXPLAIN_RELATION,
CROSS_PRODUCT_RELATION,
JOIN_RELATION,
AGGREGATE_RELATION,
SET_OPERATION_RELATION,
DISTINCT_RELATION,
LIMIT_RELATION,
ORDER_RELATION,
CREATE_VIEW_RELATION,
CREATE_TABLE_RELATION,
INSERT_RELATION,
VALUE_LIST_RELATION,
DELETE_RELATION,
UPDATE_RELATION,
WRITE_CSV_RELATION,
WRITE_PARQUET_RELATION,
READ_CSV_RELATION,
SUBQUERY_RELATION,
TABLE_FUNCTION_RELATION,
VIEW_RELATION,
QUERY_RELATION
};
string RelationTypeToString(RelationType type);
}
namespace duckdb {
class ClientContext;
class DefaultGenerator {
public:
explicit DefaultGenerator(Catalog &catalog) : catalog(catalog), created_all_entries(false) {
}
virtual ~DefaultGenerator() {
}
Catalog &catalog;
atomic<bool> created_all_entries;
public:
virtual unique_ptr<CatalogEntry> CreateDefaultEntry(ClientContext &context, const string &entry_name) = 0;
virtual vector<string> GetDefaultEntries() = 0;
};
}
namespace duckdb {
class SchemaCatalogEntry;
class StandardEntry : public CatalogEntry {
public:
StandardEntry(CatalogType type, SchemaCatalogEntry *schema, Catalog *catalog, string name)
: CatalogEntry(type, catalog, name), schema(schema) {
}
~StandardEntry() override {
}
SchemaCatalogEntry *schema;
};
}
#include <set>
namespace duckdb {
using std::set;
}
namespace duckdb {
#define SERIALIZER_DEFAULT_SIZE 1024
struct BinaryData {
unique_ptr<data_t[]> data;
idx_t size;
};
class BufferedSerializer : public Serializer {
public:
DUCKDB_API explicit BufferedSerializer(idx_t maximum_size = SERIALIZER_DEFAULT_SIZE);
BufferedSerializer(unique_ptr<data_t[]> data, idx_t size);
BufferedSerializer(data_ptr_t data, idx_t size);
idx_t maximum_size;
data_ptr_t data;
BinaryData blob;
public:
void WriteData(const_data_ptr_t buffer, uint64_t write_size) override;
BinaryData GetData() {
return std::move(blob);
}
void Reset() {
blob.size = 0;
}
};
}
#include <type_traits>
namespace duckdb {
class BufferedSerializer;
struct IndexWriteOperation {
template <class SRC, class DST>
static DST Operation(SRC input) {
return input.index;
}
};
class FieldWriter {
public:
DUCKDB_API FieldWriter(Serializer &serializer);
DUCKDB_API ~FieldWriter();
public:
template <class T>
void WriteField(const T &element) {
static_assert(std::is_trivially_destructible<T>(), "WriteField object must be trivially destructible");
AddField();
WriteData((const_data_ptr_t)&element, sizeof(T));
}
void WriteString(const string &val) {
WriteStringLen((const_data_ptr_t)val.c_str(), val.size());
}
void WriteStringLen(const_data_ptr_t val, idx_t len) {
AddField();
Write<uint32_t>((uint32_t)len);
if (len > 0) {
WriteData(val, len);
}
}
void WriteBlob(const_data_ptr_t val, idx_t len) {
AddField();
if (len > 0) {
WriteData(val, len);
}
}
template <class T, class CONTAINER_TYPE = vector<T>>
void WriteList(const CONTAINER_TYPE &elements) {
AddField();
Write<uint32_t>(elements.size());
for (auto &element : elements) {
Write<T>(element);
}
}
template <class T, class SRC, class OP, class CONTAINER_TYPE = vector<SRC>>
void WriteGenericList(const CONTAINER_TYPE &elements) {
AddField();
Write<uint32_t>(elements.size());
for (auto &element : elements) {
Write<T>(OP::template Operation<SRC, T>(element));
}
}
template <class T>
void WriteIndexList(const vector<T> &elements) {
WriteGenericList<idx_t, T, IndexWriteOperation>(elements);
}
template <class T, class CONTAINER_TYPE = vector<T>>
void WriteListNoReference(const CONTAINER_TYPE &elements) {
AddField();
Write<uint32_t>(elements.size());
for (auto element : elements) {
Write<T>(element);
}
}
template <class T>
void WriteSerializable(const T &element) {
AddField();
element.Serialize(*buffer);
}
template <class T>
void WriteSerializableList(const vector<unique_ptr<T>> &elements) {
AddField();
Write<uint32_t>(elements.size());
for (idx_t i = 0; i < elements.size(); i++) {
elements[i]->Serialize(*buffer);
}
}
template <class T>
void WriteRegularSerializableList(const vector<T> &elements) {
AddField();
Write<uint32_t>(elements.size());
for (idx_t i = 0; i < elements.size(); i++) {
elements[i].Serialize(*buffer);
}
}
template <class T>
void WriteOptional(const unique_ptr<T> &element) {
AddField();
Write<bool>(element ? true : false);
if (element) {
element->Serialize(*buffer);
}
}
DUCKDB_API void Finalize();
Serializer &GetSerializer() {
return *buffer;
}
private:
void AddField() {
field_count++;
}
template <class T>
void Write(const T &element) {
WriteData((const_data_ptr_t)&element, sizeof(T));
}
DUCKDB_API void WriteData(const_data_ptr_t buffer, idx_t write_size);
private:
Serializer &serializer;
unique_ptr<BufferedSerializer> buffer;
idx_t field_count;
bool finalized;
};
template <>
DUCKDB_API void FieldWriter::Write(const string &val);
class FieldDeserializer : public Deserializer {
public:
FieldDeserializer(Deserializer &root);
public:
void ReadData(data_ptr_t buffer, idx_t read_size) override;
void SetRemainingData(idx_t remaining_data);
idx_t RemainingData();
Deserializer &GetRoot() {
return root;
}
private:
Deserializer &root;
idx_t remaining_data;
};
struct IndexReadOperation {
template <class SRC, class DST>
static DST Operation(SRC input) {
return DST(input);
}
};
class FieldReader {
public:
DUCKDB_API FieldReader(Deserializer &source);
DUCKDB_API ~FieldReader();
public:
template <class T>
T ReadRequired() {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read a required field, but field is missing");
}
AddField();
return source.Read<T>();
}
template <class T>
T ReadField(T default_value) {
if (field_count >= max_field_count) {
return default_value;
}
AddField();
return source.Read<T>();
}
template <class T, class CONTAINER_TYPE = vector<T>>
bool ReadList(CONTAINER_TYPE &result) {
if (field_count >= max_field_count) {
return false;
}
AddField();
auto result_count = source.Read<uint32_t>();
result.reserve(result_count);
for (idx_t i = 0; i < result_count; i++) {
result.push_back(source.Read<T>());
}
return true;
}
template <class T, class CONTAINER_TYPE = vector<T>>
CONTAINER_TYPE ReadRequiredList() {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read a required field, but field is missing");
}
AddField();
auto result_count = source.Read<uint32_t>();
CONTAINER_TYPE result;
result.reserve(result_count);
for (idx_t i = 0; i < result_count; i++) {
result.push_back(source.Read<T>());
}
return result;
}
template <class T, class SRC, class OP>
vector<T> ReadRequiredGenericList() {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read a required field, but field is missing");
}
AddField();
auto result_count = source.Read<uint32_t>();
vector<T> result;
result.reserve(result_count);
for (idx_t i = 0; i < result_count; i++) {
result.push_back(OP::template Operation<SRC, T>(source.Read<SRC>()));
}
return result;
}
template <class T>
vector<T> ReadRequiredIndexList() {
return ReadRequiredGenericList<T, idx_t, IndexReadOperation>();
}
template <class T>
set<T> ReadRequiredSet() {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read a required field, but field is missing");
}
AddField();
auto result_count = source.Read<uint32_t>();
set<T> result;
for (idx_t i = 0; i < result_count; i++) {
result.insert(source.Read<T>());
}
return result;
}
template <class T, typename... ARGS>
unique_ptr<T> ReadOptional(unique_ptr<T> default_value, ARGS &&... args) {
if (field_count >= max_field_count) {
return default_value;
}
AddField();
return source.template ReadOptional<T>(std::forward<ARGS>(args)...);
}
template <class T, class RETURN_TYPE = unique_ptr<T>>
RETURN_TYPE ReadSerializable(RETURN_TYPE default_value) {
if (field_count >= max_field_count) {
return default_value;
}
AddField();
return T::Deserialize(source);
}
template <class T, class RETURN_TYPE = unique_ptr<T>, typename... ARGS>
RETURN_TYPE ReadSerializable(RETURN_TYPE default_value, ARGS &&... args) {
if (field_count >= max_field_count) {
return default_value;
}
AddField();
return T::Deserialize(source, std::forward<ARGS>(args)...);
}
template <class T, class RETURN_TYPE = unique_ptr<T>>
RETURN_TYPE ReadRequiredSerializable() {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read mandatory field, but field is missing");
}
AddField();
return T::Deserialize(source);
}
template <class T, class RETURN_TYPE = unique_ptr<T>, typename... ARGS>
RETURN_TYPE ReadRequiredSerializable(ARGS &&... args) {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read mandatory field, but field is missing");
}
AddField();
return T::Deserialize(source, std::forward<ARGS>(args)...);
}
template <class T, class RETURN_TYPE = unique_ptr<T>, typename... ARGS>
vector<RETURN_TYPE> ReadRequiredSerializableList(ARGS &&... args) {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read mandatory field, but field is missing");
}
AddField();
auto result_count = source.Read<uint32_t>();
vector<RETURN_TYPE> result;
for (idx_t i = 0; i < result_count; i++) {
result.push_back(T::Deserialize(source, std::forward<ARGS>(args)...));
}
return result;
}
void ReadBlob(data_ptr_t result, idx_t read_size) {
if (field_count >= max_field_count) {
throw SerializationException("Attempting to read a required field, but field is missing");
}
AddField();
source.ReadData(result, read_size);
}
DUCKDB_API void Finalize();
Deserializer &GetSource() {
return source;
}
private:
void AddField() {
field_count++;
}
private:
FieldDeserializer source;
idx_t field_count;
idx_t max_field_count;
idx_t total_size;
bool finalized;
};
}
namespace duckdb {
struct ParseInfo {
virtual ~ParseInfo() {
}
};
}
namespace duckdb {
struct AlterInfo;
enum class OnCreateConflict : uint8_t {
ERROR_ON_CONFLICT,
IGNORE_ON_CONFLICT,
REPLACE_ON_CONFLICT,
ALTER_ON_CONFLICT
};
struct CreateInfo : public ParseInfo {
explicit CreateInfo(CatalogType type, string schema = DEFAULT_SCHEMA, string catalog_p = INVALID_CATALOG)
: type(type), catalog(std::move(catalog_p)), schema(schema), on_conflict(OnCreateConflict::ERROR_ON_CONFLICT),
temporary(false), internal(false) {
}
~CreateInfo() override {
}
CatalogType type;
string catalog;
string schema;
OnCreateConflict on_conflict;
bool temporary;
bool internal;
string sql;
protected:
virtual void SerializeInternal(Serializer &) const = 0;
void DeserializeBase(Deserializer &deserializer);
public:
void Serialize(Serializer &serializer) const;
static unique_ptr<CreateInfo> Deserialize(Deserializer &deserializer);
static unique_ptr<CreateInfo> Deserialize(Deserializer &deserializer, PlanDeserializationState &state);
virtual unique_ptr<CreateInfo> Copy() const = 0;
DUCKDB_API void CopyProperties(CreateInfo &other) const;
DUCKDB_API virtual unique_ptr<AlterInfo> GetAlterInfo() const;
};
}
namespace duckdb {
enum class SequenceInfo : uint8_t {
SEQ_START,
SEQ_INC,
SEQ_MIN,
SEQ_MAX,
SEQ_CYCLE,
SEQ_OWN
};
struct CreateSequenceInfo : public CreateInfo {
CreateSequenceInfo()
: CreateInfo(CatalogType::SEQUENCE_ENTRY, INVALID_SCHEMA), name(string()), usage_count(0), increment(1),
min_value(1), max_value(NumericLimits<int64_t>::Maximum()), start_value(1), cycle(false) {
}
string name;
uint64_t usage_count;
int64_t increment;
int64_t min_value;
int64_t max_value;
int64_t start_value;
bool cycle;
public:
unique_ptr<CreateInfo> Copy() const override {
auto result = make_unique<CreateSequenceInfo>();
CopyProperties(*result);
result->name = name;
result->schema = schema;
result->usage_count = usage_count;
result->increment = increment;
result->min_value = min_value;
result->max_value = max_value;
result->start_value = start_value;
result->cycle = cycle;
return std::move(result);
}
protected:
void SerializeInternal(Serializer &) const override {
throw NotImplementedException("Cannot serialize '%s'", CatalogTypeToString(type));
}
};
}
namespace duckdb {
enum class AlterType : uint8_t {
INVALID = 0,
ALTER_TABLE = 1,
ALTER_VIEW = 2,
ALTER_SEQUENCE = 3,
CHANGE_OWNERSHIP = 4,
ALTER_FUNCTION = 5
};
struct AlterEntryData {
AlterEntryData() {
}
AlterEntryData(string catalog_p, string schema_p, string name_p, bool if_exists)
: catalog(std::move(catalog_p)), schema(std::move(schema_p)), name(std::move(name_p)), if_exists(if_exists) {
}
string catalog;
string schema;
string name;
bool if_exists;
};
struct AlterInfo : public ParseInfo {
AlterInfo(AlterType type, string catalog, string schema, string name, bool if_exists);
virtual ~AlterInfo() override;
AlterType type;
bool if_exists;
string catalog;
string schema;
string name;
bool allow_internal;
public:
virtual CatalogType GetCatalogType() const = 0;
virtual unique_ptr<AlterInfo> Copy() const = 0;
void Serialize(Serializer &serializer) const;
virtual void Serialize(FieldWriter &writer) const = 0;
static unique_ptr<AlterInfo> Deserialize(Deserializer &source);
AlterEntryData GetAlterEntryData() const;
};
}
namespace duckdb {
class Serializer;
class Deserializer;
class FieldWriter;
class FieldReader;
enum class ConstraintType : uint8_t {
INVALID = 0, NOT_NULL = 1, CHECK = 2, UNIQUE = 3, FOREIGN_KEY = 4, };
enum class ForeignKeyType : uint8_t {
FK_TYPE_PRIMARY_KEY_TABLE = 0, FK_TYPE_FOREIGN_KEY_TABLE = 1, FK_TYPE_SELF_REFERENCE_TABLE = 2 };
struct ForeignKeyInfo {
ForeignKeyType type;
string schema;
string table;
vector<PhysicalIndex> pk_keys;
vector<PhysicalIndex> fk_keys;
};
class Constraint {
public:
DUCKDB_API explicit Constraint(ConstraintType type);
DUCKDB_API virtual ~Constraint();
ConstraintType type;
public:
DUCKDB_API virtual string ToString() const = 0;
DUCKDB_API void Print() const;
DUCKDB_API virtual unique_ptr<Constraint> Copy() const = 0;
DUCKDB_API void Serialize(Serializer &serializer) const;
DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0;
DUCKDB_API static unique_ptr<Constraint> Deserialize(Deserializer &source);
};
}
namespace duckdb {
enum AlterForeignKeyType : uint8_t { AFT_ADD = 0, AFT_DELETE = 1 };
struct ChangeOwnershipInfo : public AlterInfo {
ChangeOwnershipInfo(CatalogType entry_catalog_type, string entry_catalog, string entry_schema, string entry_name,
string owner_schema, string owner_name, bool if_exists);
CatalogType entry_catalog_type;
string owner_schema;
string owner_name;
public:
CatalogType GetCatalogType() const override;
unique_ptr<AlterInfo> Copy() const override;
void Serialize(FieldWriter &writer) const override;
};
enum class AlterTableType : uint8_t {
INVALID = 0,
RENAME_COLUMN = 1,
RENAME_TABLE = 2,
ADD_COLUMN = 3,
REMOVE_COLUMN = 4,
ALTER_COLUMN_TYPE = 5,
SET_DEFAULT = 6,
FOREIGN_KEY_CONSTRAINT = 7,
SET_NOT_NULL = 8,
DROP_NOT_NULL = 9
};
struct AlterTableInfo : public AlterInfo {
AlterTableInfo(AlterTableType type, AlterEntryData data);
~AlterTableInfo() override;
AlterTableType alter_table_type;
public:
CatalogType GetCatalogType() const override;
void Serialize(FieldWriter &writer) const override;
virtual void SerializeAlterTable(FieldWriter &writer) const = 0;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader);
};
struct RenameColumnInfo : public AlterTableInfo {
RenameColumnInfo(AlterEntryData data, string old_name_p, string new_name_p);
~RenameColumnInfo() override;
string old_name;
string new_name;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct RenameTableInfo : public AlterTableInfo {
RenameTableInfo(AlterEntryData data, string new_name);
~RenameTableInfo() override;
string new_table_name;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct AddColumnInfo : public AlterTableInfo {
AddColumnInfo(AlterEntryData data, ColumnDefinition new_column, bool if_column_not_exists);
~AddColumnInfo() override;
ColumnDefinition new_column;
bool if_column_not_exists;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct RemoveColumnInfo : public AlterTableInfo {
RemoveColumnInfo(AlterEntryData data, string removed_column, bool if_column_exists, bool cascade);
~RemoveColumnInfo() override;
string removed_column;
bool if_column_exists;
bool cascade;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct ChangeColumnTypeInfo : public AlterTableInfo {
ChangeColumnTypeInfo(AlterEntryData data, string column_name, LogicalType target_type,
unique_ptr<ParsedExpression> expression);
~ChangeColumnTypeInfo() override;
string column_name;
LogicalType target_type;
unique_ptr<ParsedExpression> expression;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct SetDefaultInfo : public AlterTableInfo {
SetDefaultInfo(AlterEntryData data, string column_name, unique_ptr<ParsedExpression> new_default);
~SetDefaultInfo() override;
string column_name;
unique_ptr<ParsedExpression> expression;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct AlterForeignKeyInfo : public AlterTableInfo {
AlterForeignKeyInfo(AlterEntryData data, string fk_table, vector<string> pk_columns, vector<string> fk_columns,
vector<PhysicalIndex> pk_keys, vector<PhysicalIndex> fk_keys, AlterForeignKeyType type);
~AlterForeignKeyInfo() override;
string fk_table;
vector<string> pk_columns;
vector<string> fk_columns;
vector<PhysicalIndex> pk_keys;
vector<PhysicalIndex> fk_keys;
AlterForeignKeyType type;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct SetNotNullInfo : public AlterTableInfo {
SetNotNullInfo(AlterEntryData data, string column_name);
~SetNotNullInfo() override;
string column_name;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
struct DropNotNullInfo : public AlterTableInfo {
DropNotNullInfo(AlterEntryData data, string column_name);
~DropNotNullInfo() override;
string column_name;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterTable(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
enum class AlterViewType : uint8_t { INVALID = 0, RENAME_VIEW = 1 };
struct AlterViewInfo : public AlterInfo {
AlterViewInfo(AlterViewType type, AlterEntryData data);
~AlterViewInfo() override;
AlterViewType alter_view_type;
public:
CatalogType GetCatalogType() const override;
void Serialize(FieldWriter &writer) const override;
virtual void SerializeAlterView(FieldWriter &writer) const = 0;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader);
};
struct RenameViewInfo : public AlterViewInfo {
RenameViewInfo(AlterEntryData data, string new_name);
~RenameViewInfo() override;
string new_view_name;
public:
unique_ptr<AlterInfo> Copy() const override;
void SerializeAlterView(FieldWriter &writer) const override;
static unique_ptr<AlterInfo> Deserialize(FieldReader &reader, AlterEntryData data);
};
}
namespace duckdb {
class Serializer;
class Deserializer;
struct SequenceValue {
SequenceValue() : usage_count(0), counter(-1) {
}
SequenceValue(uint64_t usage_count, int64_t counter) : usage_count(usage_count), counter(counter) {
}
uint64_t usage_count;
int64_t counter;
};
class SequenceCatalogEntry : public StandardEntry {
public:
static constexpr const CatalogType Type = CatalogType::SEQUENCE_ENTRY;
static constexpr const char *Name = "sequence";
public:
SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info);
mutex lock;
uint64_t usage_count;
int64_t counter;
int64_t last_value;
int64_t increment;
int64_t start_value;
int64_t min_value;
int64_t max_value;
bool cycle;
public:
virtual void Serialize(Serializer &serializer);
static unique_ptr<CreateSequenceInfo> Deserialize(Deserializer &source);
string ToSQL() override;
CatalogEntry *AlterOwnership(ClientContext &context, AlterInfo *info);
};
}
namespace duckdb {
enum class UndoFlags : uint32_t { EMPTY_ENTRY = 0,
CATALOG_ENTRY = 1,
INSERT_TUPLE = 2,
DELETE_TUPLE = 3,
UPDATE_TUPLE = 4
};
}
namespace duckdb {
class WriteAheadLog;
class UndoBuffer {
public:
struct IteratorState {
ArenaChunk *current;
data_ptr_t start;
data_ptr_t end;
};
public:
UndoBuffer(ClientContext &context);
data_ptr_t CreateEntry(UndoFlags type, idx_t len);
bool ChangesMade();
idx_t EstimatedSize();
void Cleanup();
void Commit(UndoBuffer::IteratorState &iterator_state, WriteAheadLog *log, transaction_t commit_id);
void RevertCommit(UndoBuffer::IteratorState &iterator_state, transaction_t transaction_id);
void Rollback() noexcept;
private:
ClientContext &context;
ArenaAllocator allocator;
private:
template <class T>
void IterateEntries(UndoBuffer::IteratorState &state, T &&callback);
template <class T>
void IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback);
template <class T>
void ReverseIterateEntries(T &&callback);
};
}
namespace duckdb {
class DuckTransaction;
class Transaction;
struct TransactionData {
TransactionData(DuckTransaction &transaction_p);
TransactionData(transaction_t transaction_id_p, transaction_t start_time_p);
DuckTransaction *transaction;
transaction_t transaction_id;
transaction_t start_time;
};
}
namespace duckdb {
class SequenceCatalogEntry;
class SchemaCatalogEntry;
class AttachedDatabase;
class ColumnData;
class ClientContext;
class CatalogEntry;
class DataTable;
class DatabaseInstance;
class LocalStorage;
class MetaTransaction;
class TransactionManager;
class WriteAheadLog;
class ChunkVectorInfo;
struct DeleteInfo;
struct UpdateInfo;
class Transaction {
public:
DUCKDB_API Transaction(TransactionManager &manager, ClientContext &context);
DUCKDB_API virtual ~Transaction();
TransactionManager &manager;
weak_ptr<ClientContext> context;
atomic<transaction_t> active_query;
public:
DUCKDB_API static Transaction &Get(ClientContext &context, AttachedDatabase &db);
DUCKDB_API static Transaction &Get(ClientContext &context, Catalog &catalog);
DUCKDB_API bool IsReadOnly();
virtual bool IsDuckTransaction() const {
return false;
}
};
}
namespace duckdb {
class SchemaCatalogEntry;
struct SimilarCatalogEntry {
string name;
idx_t distance = idx_t(-1);
SchemaCatalogEntry *schema = nullptr;
DUCKDB_API bool Found() const {
return !name.empty();
}
DUCKDB_API string GetQualifiedName(bool qualify_catalog, bool qualify_schema) const;
};
}
#include <functional>
#include <memory>
namespace duckdb {
struct AlterInfo;
class ClientContext;
class DependencyList;
struct MappingValue;
struct EntryIndex;
class DuckCatalog;
class TableCatalogEntry;
class SequenceCatalogEntry;
typedef unordered_map<CatalogSet *, unique_lock<mutex>> set_lock_map_t;
struct EntryValue {
EntryValue() {
throw InternalException("EntryValue called without a catalog entry");
}
explicit EntryValue(unique_ptr<CatalogEntry> entry_p) : entry(std::move(entry_p)), reference_count(0) {
}
EntryValue(EntryValue &&other) noexcept {
Swap(other);
}
EntryValue &operator=(EntryValue &&other) noexcept {
Swap(other);
return *this;
}
void Swap(EntryValue &other) {
std::swap(entry, other.entry);
idx_t count = reference_count;
reference_count = other.reference_count.load();
other.reference_count = count;
}
unique_ptr<CatalogEntry> entry;
atomic<idx_t> reference_count;
};
class CatalogSet {
friend class DependencyManager;
friend class EntryDropper;
friend struct EntryIndex;
public:
DUCKDB_API explicit CatalogSet(Catalog &catalog, unique_ptr<DefaultGenerator> defaults = nullptr);
~CatalogSet();
DUCKDB_API bool CreateEntry(CatalogTransaction transaction, const string &name, unique_ptr<CatalogEntry> value,
DependencyList &dependencies);
DUCKDB_API bool CreateEntry(ClientContext &context, const string &name, unique_ptr<CatalogEntry> value,
DependencyList &dependencies);
DUCKDB_API bool AlterEntry(CatalogTransaction transaction, const string &name, AlterInfo *alter_info);
DUCKDB_API bool DropEntry(CatalogTransaction transaction, const string &name, bool cascade,
bool allow_drop_internal = false);
DUCKDB_API bool DropEntry(ClientContext &context, const string &name, bool cascade,
bool allow_drop_internal = false);
DUCKDB_API DuckCatalog &GetCatalog();
bool AlterOwnership(CatalogTransaction transaction, ChangeOwnershipInfo *info);
void CleanupEntry(CatalogEntry *catalog_entry);
DUCKDB_API CatalogEntry *GetEntry(CatalogTransaction transaction, const string &name);
DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, const string &name);
SimilarCatalogEntry SimilarEntry(CatalogTransaction transaction, const string &name);
void Undo(CatalogEntry *entry);
DUCKDB_API void Scan(const std::function<void(CatalogEntry *)> &callback);
DUCKDB_API void Scan(CatalogTransaction transaction, const std::function<void(CatalogEntry *)> &callback);
DUCKDB_API void Scan(ClientContext &context, const std::function<void(CatalogEntry *)> &callback);
template <class T>
vector<T *> GetEntries(CatalogTransaction transaction) {
vector<T *> result;
Scan(transaction, [&](CatalogEntry *entry) { result.push_back((T *)entry); });
return result;
}
DUCKDB_API bool HasConflict(CatalogTransaction transaction, transaction_t timestamp);
DUCKDB_API bool UseTimestamp(CatalogTransaction transaction, transaction_t timestamp);
void UpdateTimestamp(CatalogEntry *entry, transaction_t timestamp);
void Verify(Catalog &catalog);
private:
void AdjustTableDependencies(CatalogEntry *entry);
void AdjustDependency(CatalogEntry *entry, TableCatalogEntry *table, ColumnDefinition &column, bool remove);
void AdjustUserDependency(CatalogEntry *entry, ColumnDefinition &column, bool remove);
CatalogEntry *GetEntryForTransaction(CatalogTransaction transaction, CatalogEntry *current);
CatalogEntry *GetCommittedEntry(CatalogEntry *current);
bool GetEntryInternal(CatalogTransaction transaction, const string &name, EntryIndex *entry_index,
CatalogEntry *&entry);
bool GetEntryInternal(CatalogTransaction transaction, EntryIndex &entry_index, CatalogEntry *&entry);
void DropEntryInternal(CatalogTransaction transaction, EntryIndex entry_index, CatalogEntry &entry, bool cascade);
CatalogEntry *CreateEntryInternal(CatalogTransaction transaction, unique_ptr<CatalogEntry> entry);
MappingValue *GetMapping(CatalogTransaction transaction, const string &name, bool get_latest = false);
void PutMapping(CatalogTransaction transaction, const string &name, EntryIndex entry_index);
void DeleteMapping(CatalogTransaction transaction, const string &name);
void DropEntryDependencies(CatalogTransaction transaction, EntryIndex &entry_index, CatalogEntry &entry,
bool cascade);
void CreateDefaultEntries(CatalogTransaction transaction, unique_lock<mutex> &lock);
CatalogEntry *CreateDefaultEntry(CatalogTransaction transaction, const string &name, unique_lock<mutex> &lock);
EntryIndex PutEntry(idx_t entry_index, unique_ptr<CatalogEntry> entry);
void PutEntry(EntryIndex index, unique_ptr<CatalogEntry> entry);
private:
DuckCatalog &catalog;
mutex catalog_lock;
unordered_map<idx_t, EntryValue> entries;
case_insensitive_map_t<unique_ptr<MappingValue>> mapping;
idx_t current_entry = 0;
unique_ptr<DefaultGenerator> defaults;
};
}
namespace duckdb {
class ClientContext;
class StandardEntry;
class TableCatalogEntry;
class TableFunctionCatalogEntry;
class SequenceCatalogEntry;
class Serializer;
class Deserializer;
enum class OnCreateConflict : uint8_t;
struct AlterTableInfo;
struct CreateIndexInfo;
struct CreateFunctionInfo;
struct CreateCollationInfo;
struct CreateViewInfo;
struct BoundCreateTableInfo;
struct CreatePragmaFunctionInfo;
struct CreateSequenceInfo;
struct CreateSchemaInfo;
struct CreateTableFunctionInfo;
struct CreateCopyFunctionInfo;
struct CreateTypeInfo;
struct DropInfo;
class SchemaCatalogEntry : public CatalogEntry {
public:
static constexpr const CatalogType Type = CatalogType::SCHEMA_ENTRY;
static constexpr const char *Name = "schema";
public:
SchemaCatalogEntry(Catalog *catalog, string name, bool is_internal);
public:
virtual void Scan(ClientContext &context, CatalogType type,
const std::function<void(CatalogEntry *)> &callback) = 0;
virtual void Scan(CatalogType type, const std::function<void(CatalogEntry *)> &callback) = 0;
virtual void Serialize(Serializer &serializer);
static unique_ptr<CreateSchemaInfo> Deserialize(Deserializer &source);
string ToSQL() override;
virtual CatalogEntry *CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table) = 0;
virtual CatalogEntry *CreateFunction(CatalogTransaction transaction, CreateFunctionInfo *info) = 0;
virtual CatalogEntry *CreateTable(CatalogTransaction transaction, BoundCreateTableInfo *info) = 0;
virtual CatalogEntry *CreateView(CatalogTransaction transaction, CreateViewInfo *info) = 0;
virtual CatalogEntry *CreateSequence(CatalogTransaction transaction, CreateSequenceInfo *info) = 0;
virtual CatalogEntry *CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo *info) = 0;
virtual CatalogEntry *CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo *info) = 0;
virtual CatalogEntry *CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo *info) = 0;
virtual CatalogEntry *CreateCollation(CatalogTransaction transaction, CreateCollationInfo *info) = 0;
virtual CatalogEntry *CreateType(CatalogTransaction transaction, CreateTypeInfo *info) = 0;
DUCKDB_API virtual CatalogEntry *GetEntry(CatalogTransaction transaction, CatalogType type, const string &name) = 0;
DUCKDB_API virtual SimilarCatalogEntry GetSimilarEntry(CatalogTransaction transaction, CatalogType type,
const string &name);
virtual void DropEntry(ClientContext &context, DropInfo *info) = 0;
virtual void Alter(ClientContext &context, AlterInfo *info) = 0;
CatalogTransaction GetCatalogTransaction(ClientContext &context);
};
}
#include <deque>
namespace duckdb {
using std::deque;
}
namespace duckdb {
class ClientContext;
class ClientContextLock;
class Executor;
class MaterializedQueryResult;
class PreparedStatementData;
class StreamQueryResult : public QueryResult {
friend class ClientContext;
public:
DUCKDB_API StreamQueryResult(StatementType statement_type, StatementProperties properties,
shared_ptr<ClientContext> context, vector<LogicalType> types, vector<string> names);
DUCKDB_API ~StreamQueryResult() override;
public:
DUCKDB_API unique_ptr<DataChunk> FetchRaw() override;
DUCKDB_API string ToString() override;
DUCKDB_API unique_ptr<MaterializedQueryResult> Materialize();
DUCKDB_API bool IsOpen();
DUCKDB_API void Close();
shared_ptr<ClientContext> context;
private:
unique_ptr<ClientContextLock> LockContext();
void CheckExecutableInternal(ClientContextLock &lock);
bool IsOpenInternal(ClientContextLock &lock);
};
}
namespace duckdb {
struct TableDescription {
string schema;
string table;
vector<ColumnDefinition> columns;
};
}
namespace duckdb {
class ClientContext;
class MetaTransaction;
class Transaction;
class TransactionManager;
class TransactionContext {
public:
TransactionContext(ClientContext &context);
~TransactionContext();
MetaTransaction &ActiveTransaction() {
if (!current_transaction) {
throw InternalException("TransactionContext::ActiveTransaction called without active transaction");
}
return *current_transaction;
}
bool HasActiveTransaction() {
return !!current_transaction;
}
void BeginTransaction();
void Commit();
void Rollback();
void ClearTransaction();
void SetAutoCommit(bool value);
bool IsAutoCommit() {
return auto_commit;
}
idx_t GetActiveQuery();
void ResetActiveQuery();
void SetActiveQuery(transaction_t query_number);
private:
ClientContext &context;
bool auto_commit;
unique_ptr<MetaTransaction> current_transaction;
TransactionContext(const TransactionContext &) = delete;
};
}
namespace duckdb {
enum class ExplainOutputType : uint8_t { ALL = 0, OPTIMIZED_ONLY = 1, PHYSICAL_ONLY = 2 };
}
#ifndef DUCKDB_API
#ifdef _WIN32
#if defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION)
#define DUCKDB_API __declspec(dllexport)
#else
#define DUCKDB_API __declspec(dllimport)
#endif
#else
#define DUCKDB_API
#endif
#endif
#ifndef DUCKDB_EXTENSION_API
#ifdef _WIN32
#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION
#define DUCKDB_EXTENSION_API __declspec(dllexport)
#else
#define DUCKDB_EXTENSION_API
#endif
#else
#define DUCKDB_EXTENSION_API __attribute__((visibility("default")))
#endif
#endif
#ifndef DUCKDB_API_0_3_1
#define DUCKDB_API_0_3_1 1
#endif
#ifndef DUCKDB_API_0_3_2
#define DUCKDB_API_0_3_2 2
#endif
#ifndef DUCKDB_API_LATEST
#define DUCKDB_API_LATEST DUCKDB_API_0_3_2
#endif
#ifndef DUCKDB_API_VERSION
#define DUCKDB_API_VERSION DUCKDB_API_LATEST
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t idx_t;
typedef enum DUCKDB_TYPE {
DUCKDB_TYPE_INVALID = 0,
DUCKDB_TYPE_BOOLEAN,
DUCKDB_TYPE_TINYINT,
DUCKDB_TYPE_SMALLINT,
DUCKDB_TYPE_INTEGER,
DUCKDB_TYPE_BIGINT,
DUCKDB_TYPE_UTINYINT,
DUCKDB_TYPE_USMALLINT,
DUCKDB_TYPE_UINTEGER,
DUCKDB_TYPE_UBIGINT,
DUCKDB_TYPE_FLOAT,
DUCKDB_TYPE_DOUBLE,
DUCKDB_TYPE_TIMESTAMP,
DUCKDB_TYPE_DATE,
DUCKDB_TYPE_TIME,
DUCKDB_TYPE_INTERVAL,
DUCKDB_TYPE_HUGEINT,
DUCKDB_TYPE_VARCHAR,
DUCKDB_TYPE_BLOB,
DUCKDB_TYPE_DECIMAL,
DUCKDB_TYPE_TIMESTAMP_S,
DUCKDB_TYPE_TIMESTAMP_MS,
DUCKDB_TYPE_TIMESTAMP_NS,
DUCKDB_TYPE_ENUM,
DUCKDB_TYPE_LIST,
DUCKDB_TYPE_STRUCT,
DUCKDB_TYPE_MAP,
DUCKDB_TYPE_UUID,
DUCKDB_TYPE_UNION,
DUCKDB_TYPE_BIT,
} duckdb_type;
typedef struct {
int32_t days;
} duckdb_date;
typedef struct {
int32_t year;
int8_t month;
int8_t day;
} duckdb_date_struct;
typedef struct {
int64_t micros;
} duckdb_time;
typedef struct {
int8_t hour;
int8_t min;
int8_t sec;
int32_t micros;
} duckdb_time_struct;
typedef struct {
int64_t micros;
} duckdb_timestamp;
typedef struct {
duckdb_date_struct date;
duckdb_time_struct time;
} duckdb_timestamp_struct;
typedef struct {
int32_t months;
int32_t days;
int64_t micros;
} duckdb_interval;
typedef struct {
uint64_t lower;
int64_t upper;
} duckdb_hugeint;
typedef struct {
uint8_t width;
uint8_t scale;
duckdb_hugeint value;
} duckdb_decimal;
typedef struct {
char *data;
idx_t size;
} duckdb_string;
typedef struct {
void *data;
idx_t size;
} duckdb_blob;
typedef struct {
uint64_t offset;
uint64_t length;
} duckdb_list_entry;
typedef struct {
#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2
void *data;
bool *nullmask;
duckdb_type type;
char *name;
#else
void *__deprecated_data;
bool *__deprecated_nullmask;
duckdb_type __deprecated_type;
char *__deprecated_name;
#endif
void *internal_data;
} duckdb_column;
typedef struct {
#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2
idx_t column_count;
idx_t row_count;
idx_t rows_changed;
duckdb_column *columns;
char *error_message;
#else
idx_t __deprecated_column_count;
idx_t __deprecated_row_count;
idx_t __deprecated_rows_changed;
duckdb_column *__deprecated_columns;
char *__deprecated_error_message;
#endif
void *internal_data;
} duckdb_result;
typedef struct _duckdb_database {
void *__db;
} * duckdb_database;
typedef struct _duckdb_connection {
void *__conn;
} * duckdb_connection;
typedef struct _duckdb_prepared_statement {
void *__prep;
} * duckdb_prepared_statement;
typedef struct _duckdb_extracted_statements {
void *__extrac;
} * duckdb_extracted_statements;
typedef struct _duckdb_pending_result {
void *__pend;
} * duckdb_pending_result;
typedef struct _duckdb_appender {
void *__appn;
} * duckdb_appender;
typedef struct _duckdb_arrow {
void *__arrw;
} * duckdb_arrow;
typedef struct _duckdb_config {
void *__cnfg;
} * duckdb_config;
typedef struct _duckdb_arrow_schema {
void *__arrs;
} * duckdb_arrow_schema;
typedef struct _duckdb_arrow_array {
void *__arra;
} * duckdb_arrow_array;
typedef struct _duckdb_logical_type {
void *__lglt;
} * duckdb_logical_type;
typedef struct _duckdb_data_chunk {
void *__dtck;
} * duckdb_data_chunk;
typedef struct _duckdb_vector {
void *__vctr;
} * duckdb_vector;
typedef struct _duckdb_value {
void *__val;
} * duckdb_value;
typedef enum { DuckDBSuccess = 0, DuckDBError = 1 } duckdb_state;
typedef enum {
DUCKDB_PENDING_RESULT_READY = 0,
DUCKDB_PENDING_RESULT_NOT_READY = 1,
DUCKDB_PENDING_ERROR = 2
} duckdb_pending_state;
DUCKDB_API duckdb_state duckdb_open(const char *path, duckdb_database *out_database);
DUCKDB_API duckdb_state duckdb_open_ext(const char *path, duckdb_database *out_database, duckdb_config config,
char **out_error);
DUCKDB_API void duckdb_close(duckdb_database *database);
DUCKDB_API duckdb_state duckdb_connect(duckdb_database database, duckdb_connection *out_connection);
DUCKDB_API void duckdb_disconnect(duckdb_connection *connection);
DUCKDB_API const char *duckdb_library_version();
DUCKDB_API duckdb_state duckdb_create_config(duckdb_config *out_config);
DUCKDB_API size_t duckdb_config_count();
DUCKDB_API duckdb_state duckdb_get_config_flag(size_t index, const char **out_name, const char **out_description);
DUCKDB_API duckdb_state duckdb_set_config(duckdb_config config, const char *name, const char *option);
DUCKDB_API void duckdb_destroy_config(duckdb_config *config);
DUCKDB_API duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out_result);
DUCKDB_API void duckdb_destroy_result(duckdb_result *result);
DUCKDB_API const char *duckdb_column_name(duckdb_result *result, idx_t col);
DUCKDB_API duckdb_type duckdb_column_type(duckdb_result *result, idx_t col);
DUCKDB_API duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col);
DUCKDB_API idx_t duckdb_column_count(duckdb_result *result);
DUCKDB_API idx_t duckdb_row_count(duckdb_result *result);
DUCKDB_API idx_t duckdb_rows_changed(duckdb_result *result);
DUCKDB_API void *duckdb_column_data(duckdb_result *result, idx_t col);
DUCKDB_API bool *duckdb_nullmask_data(duckdb_result *result, idx_t col);
DUCKDB_API const char *duckdb_result_error(duckdb_result *result);
DUCKDB_API duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_index);
DUCKDB_API idx_t duckdb_result_chunk_count(duckdb_result result);
DUCKDB_API bool duckdb_value_boolean(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API int8_t duckdb_value_int8(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API int16_t duckdb_value_int16(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API int32_t duckdb_value_int32(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API uint8_t duckdb_value_uint8(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API uint16_t duckdb_value_uint16(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API uint32_t duckdb_value_uint32(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API uint64_t duckdb_value_uint64(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API float duckdb_value_float(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API double duckdb_value_double(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_date duckdb_value_date(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_time duckdb_value_time(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_timestamp duckdb_value_timestamp(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_string duckdb_value_string(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_string duckdb_value_string_internal(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row);
DUCKDB_API void *duckdb_malloc(size_t size);
DUCKDB_API void duckdb_free(void *ptr);
DUCKDB_API idx_t duckdb_vector_size();
DUCKDB_API duckdb_date_struct duckdb_from_date(duckdb_date date);
DUCKDB_API duckdb_date duckdb_to_date(duckdb_date_struct date);
DUCKDB_API duckdb_time_struct duckdb_from_time(duckdb_time time);
DUCKDB_API duckdb_time duckdb_to_time(duckdb_time_struct time);
DUCKDB_API duckdb_timestamp_struct duckdb_from_timestamp(duckdb_timestamp ts);
DUCKDB_API duckdb_timestamp duckdb_to_timestamp(duckdb_timestamp_struct ts);
DUCKDB_API double duckdb_hugeint_to_double(duckdb_hugeint val);
DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val);
DUCKDB_API duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale);
DUCKDB_API double duckdb_decimal_to_double(duckdb_decimal val);
DUCKDB_API duckdb_state duckdb_prepare(duckdb_connection connection, const char *query,
duckdb_prepared_statement *out_prepared_statement);
DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement);
DUCKDB_API const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement);
DUCKDB_API idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement);
DUCKDB_API duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_t param_idx);
DUCKDB_API duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement);
DUCKDB_API duckdb_state duckdb_bind_boolean(duckdb_prepared_statement prepared_statement, idx_t param_idx, bool val);
DUCKDB_API duckdb_state duckdb_bind_int8(duckdb_prepared_statement prepared_statement, idx_t param_idx, int8_t val);
DUCKDB_API duckdb_state duckdb_bind_int16(duckdb_prepared_statement prepared_statement, idx_t param_idx, int16_t val);
DUCKDB_API duckdb_state duckdb_bind_int32(duckdb_prepared_statement prepared_statement, idx_t param_idx, int32_t val);
DUCKDB_API duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx_t param_idx, int64_t val);
DUCKDB_API duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx,
duckdb_hugeint val);
DUCKDB_API duckdb_state duckdb_bind_decimal(duckdb_prepared_statement prepared_statement, idx_t param_idx,
duckdb_decimal val);
DUCKDB_API duckdb_state duckdb_bind_uint8(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint8_t val);
DUCKDB_API duckdb_state duckdb_bind_uint16(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint16_t val);
DUCKDB_API duckdb_state duckdb_bind_uint32(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint32_t val);
DUCKDB_API duckdb_state duckdb_bind_uint64(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint64_t val);
DUCKDB_API duckdb_state duckdb_bind_float(duckdb_prepared_statement prepared_statement, idx_t param_idx, float val);
DUCKDB_API duckdb_state duckdb_bind_double(duckdb_prepared_statement prepared_statement, idx_t param_idx, double val);
DUCKDB_API duckdb_state duckdb_bind_date(duckdb_prepared_statement prepared_statement, idx_t param_idx,
duckdb_date val);
DUCKDB_API duckdb_state duckdb_bind_time(duckdb_prepared_statement prepared_statement, idx_t param_idx,
duckdb_time val);
DUCKDB_API duckdb_state duckdb_bind_timestamp(duckdb_prepared_statement prepared_statement, idx_t param_idx,
duckdb_timestamp val);
DUCKDB_API duckdb_state duckdb_bind_interval(duckdb_prepared_statement prepared_statement, idx_t param_idx,
duckdb_interval val);
DUCKDB_API duckdb_state duckdb_bind_varchar(duckdb_prepared_statement prepared_statement, idx_t param_idx,
const char *val);
DUCKDB_API duckdb_state duckdb_bind_varchar_length(duckdb_prepared_statement prepared_statement, idx_t param_idx,
const char *val, idx_t length);
DUCKDB_API duckdb_state duckdb_bind_blob(duckdb_prepared_statement prepared_statement, idx_t param_idx,
const void *data, idx_t length);
DUCKDB_API duckdb_state duckdb_bind_null(duckdb_prepared_statement prepared_statement, idx_t param_idx);
DUCKDB_API duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statement,
duckdb_result *out_result);
DUCKDB_API duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_statement,
duckdb_arrow *out_result);
DUCKDB_API idx_t duckdb_extract_statements(duckdb_connection connection, const char *query,
duckdb_extracted_statements *out_extracted_statements);
DUCKDB_API duckdb_state duckdb_prepare_extracted_statement(duckdb_connection connection,
duckdb_extracted_statements extracted_statements,
idx_t index,
duckdb_prepared_statement *out_prepared_statement);
DUCKDB_API const char *duckdb_extract_statements_error(duckdb_extracted_statements extracted_statements);
DUCKDB_API void duckdb_destroy_extracted(duckdb_extracted_statements *extracted_statements);
DUCKDB_API duckdb_state duckdb_pending_prepared(duckdb_prepared_statement prepared_statement,
duckdb_pending_result *out_result);
DUCKDB_API void duckdb_destroy_pending(duckdb_pending_result *pending_result);
DUCKDB_API const char *duckdb_pending_error(duckdb_pending_result pending_result);
DUCKDB_API duckdb_pending_state duckdb_pending_execute_task(duckdb_pending_result pending_result);
DUCKDB_API duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb_result *out_result);
DUCKDB_API void duckdb_destroy_value(duckdb_value *value);
DUCKDB_API duckdb_value duckdb_create_varchar(const char *text);
DUCKDB_API duckdb_value duckdb_create_varchar_length(const char *text, idx_t length);
DUCKDB_API duckdb_value duckdb_create_int64(int64_t val);
DUCKDB_API char *duckdb_get_varchar(duckdb_value value);
DUCKDB_API int64_t duckdb_get_int64(duckdb_value value);
DUCKDB_API duckdb_logical_type duckdb_create_logical_type(duckdb_type type);
DUCKDB_API duckdb_logical_type duckdb_create_list_type(duckdb_logical_type type);
DUCKDB_API duckdb_logical_type duckdb_create_map_type(duckdb_logical_type key_type, duckdb_logical_type value_type);
DUCKDB_API duckdb_logical_type duckdb_create_union_type(duckdb_logical_type member_types, const char **member_names,
idx_t member_count);
DUCKDB_API duckdb_logical_type duckdb_create_decimal_type(uint8_t width, uint8_t scale);
DUCKDB_API duckdb_type duckdb_get_type_id(duckdb_logical_type type);
DUCKDB_API uint8_t duckdb_decimal_width(duckdb_logical_type type);
DUCKDB_API uint8_t duckdb_decimal_scale(duckdb_logical_type type);
DUCKDB_API duckdb_type duckdb_decimal_internal_type(duckdb_logical_type type);
DUCKDB_API duckdb_type duckdb_enum_internal_type(duckdb_logical_type type);
DUCKDB_API uint32_t duckdb_enum_dictionary_size(duckdb_logical_type type);
DUCKDB_API char *duckdb_enum_dictionary_value(duckdb_logical_type type, idx_t index);
DUCKDB_API duckdb_logical_type duckdb_list_type_child_type(duckdb_logical_type type);
DUCKDB_API duckdb_logical_type duckdb_map_type_key_type(duckdb_logical_type type);
DUCKDB_API duckdb_logical_type duckdb_map_type_value_type(duckdb_logical_type type);
DUCKDB_API idx_t duckdb_struct_type_child_count(duckdb_logical_type type);
DUCKDB_API char *duckdb_struct_type_child_name(duckdb_logical_type type, idx_t index);
DUCKDB_API duckdb_logical_type duckdb_struct_type_child_type(duckdb_logical_type type, idx_t index);
DUCKDB_API idx_t duckdb_union_type_member_count(duckdb_logical_type type);
DUCKDB_API char *duckdb_union_type_member_name(duckdb_logical_type type, idx_t index);
DUCKDB_API duckdb_logical_type duckdb_union_type_member_type(duckdb_logical_type type, idx_t index);
DUCKDB_API void duckdb_destroy_logical_type(duckdb_logical_type *type);
DUCKDB_API duckdb_data_chunk duckdb_create_data_chunk(duckdb_logical_type *types, idx_t column_count);
DUCKDB_API void duckdb_destroy_data_chunk(duckdb_data_chunk *chunk);
DUCKDB_API void duckdb_data_chunk_reset(duckdb_data_chunk chunk);
DUCKDB_API idx_t duckdb_data_chunk_get_column_count(duckdb_data_chunk chunk);
DUCKDB_API duckdb_vector duckdb_data_chunk_get_vector(duckdb_data_chunk chunk, idx_t col_idx);
DUCKDB_API idx_t duckdb_data_chunk_get_size(duckdb_data_chunk chunk);
DUCKDB_API void duckdb_data_chunk_set_size(duckdb_data_chunk chunk, idx_t size);
DUCKDB_API duckdb_logical_type duckdb_vector_get_column_type(duckdb_vector vector);
DUCKDB_API void *duckdb_vector_get_data(duckdb_vector vector);
DUCKDB_API uint64_t *duckdb_vector_get_validity(duckdb_vector vector);
DUCKDB_API void duckdb_vector_ensure_validity_writable(duckdb_vector vector);
DUCKDB_API void duckdb_vector_assign_string_element(duckdb_vector vector, idx_t index, const char *str);
DUCKDB_API void duckdb_vector_assign_string_element_len(duckdb_vector vector, idx_t index, const char *str,
idx_t str_len);
DUCKDB_API duckdb_vector duckdb_list_vector_get_child(duckdb_vector vector);
DUCKDB_API idx_t duckdb_list_vector_get_size(duckdb_vector vector);
DUCKDB_API duckdb_state duckdb_list_vector_set_size(duckdb_vector vector, idx_t size);
DUCKDB_API duckdb_state duckdb_list_vector_reserve(duckdb_vector vector, idx_t required_capacity);
DUCKDB_API duckdb_vector duckdb_struct_vector_get_child(duckdb_vector vector, idx_t index);
DUCKDB_API bool duckdb_validity_row_is_valid(uint64_t *validity, idx_t row);
DUCKDB_API void duckdb_validity_set_row_validity(uint64_t *validity, idx_t row, bool valid);
DUCKDB_API void duckdb_validity_set_row_invalid(uint64_t *validity, idx_t row);
DUCKDB_API void duckdb_validity_set_row_valid(uint64_t *validity, idx_t row);
typedef void *duckdb_table_function;
typedef void *duckdb_bind_info;
typedef void *duckdb_init_info;
typedef void *duckdb_function_info;
typedef void (*duckdb_table_function_bind_t)(duckdb_bind_info info);
typedef void (*duckdb_table_function_init_t)(duckdb_init_info info);
typedef void (*duckdb_table_function_t)(duckdb_function_info info, duckdb_data_chunk output);
typedef void (*duckdb_delete_callback_t)(void *data);
DUCKDB_API duckdb_table_function duckdb_create_table_function();
DUCKDB_API void duckdb_destroy_table_function(duckdb_table_function *table_function);
DUCKDB_API void duckdb_table_function_set_name(duckdb_table_function table_function, const char *name);
DUCKDB_API void duckdb_table_function_add_parameter(duckdb_table_function table_function, duckdb_logical_type type);
DUCKDB_API void duckdb_table_function_set_extra_info(duckdb_table_function table_function, void *extra_info,
duckdb_delete_callback_t destroy);
DUCKDB_API void duckdb_table_function_set_bind(duckdb_table_function table_function, duckdb_table_function_bind_t bind);
DUCKDB_API void duckdb_table_function_set_init(duckdb_table_function table_function, duckdb_table_function_init_t init);
DUCKDB_API void duckdb_table_function_set_local_init(duckdb_table_function table_function,
duckdb_table_function_init_t init);
DUCKDB_API void duckdb_table_function_set_function(duckdb_table_function table_function,
duckdb_table_function_t function);
DUCKDB_API void duckdb_table_function_supports_projection_pushdown(duckdb_table_function table_function, bool pushdown);
DUCKDB_API duckdb_state duckdb_register_table_function(duckdb_connection con, duckdb_table_function function);
DUCKDB_API void *duckdb_bind_get_extra_info(duckdb_bind_info info);
DUCKDB_API void duckdb_bind_add_result_column(duckdb_bind_info info, const char *name, duckdb_logical_type type);
DUCKDB_API idx_t duckdb_bind_get_parameter_count(duckdb_bind_info info);
DUCKDB_API duckdb_value duckdb_bind_get_parameter(duckdb_bind_info info, idx_t index);
DUCKDB_API void duckdb_bind_set_bind_data(duckdb_bind_info info, void *bind_data, duckdb_delete_callback_t destroy);
DUCKDB_API void duckdb_bind_set_cardinality(duckdb_bind_info info, idx_t cardinality, bool is_exact);
DUCKDB_API void duckdb_bind_set_error(duckdb_bind_info info, const char *error);
DUCKDB_API void *duckdb_init_get_extra_info(duckdb_init_info info);
DUCKDB_API void *duckdb_init_get_bind_data(duckdb_init_info info);
DUCKDB_API void duckdb_init_set_init_data(duckdb_init_info info, void *init_data, duckdb_delete_callback_t destroy);
DUCKDB_API idx_t duckdb_init_get_column_count(duckdb_init_info info);
DUCKDB_API idx_t duckdb_init_get_column_index(duckdb_init_info info, idx_t column_index);
DUCKDB_API void duckdb_init_set_max_threads(duckdb_init_info info, idx_t max_threads);
DUCKDB_API void duckdb_init_set_error(duckdb_init_info info, const char *error);
DUCKDB_API void *duckdb_function_get_extra_info(duckdb_function_info info);
DUCKDB_API void *duckdb_function_get_bind_data(duckdb_function_info info);
DUCKDB_API void *duckdb_function_get_init_data(duckdb_function_info info);
DUCKDB_API void *duckdb_function_get_local_init_data(duckdb_function_info info);
DUCKDB_API void duckdb_function_set_error(duckdb_function_info info, const char *error);
typedef void *duckdb_replacement_scan_info;
typedef void (*duckdb_replacement_callback_t)(duckdb_replacement_scan_info info, const char *table_name, void *data);
DUCKDB_API void duckdb_add_replacement_scan(duckdb_database db, duckdb_replacement_callback_t replacement,
void *extra_data, duckdb_delete_callback_t delete_callback);
DUCKDB_API void duckdb_replacement_scan_set_function_name(duckdb_replacement_scan_info info, const char *function_name);
DUCKDB_API void duckdb_replacement_scan_add_parameter(duckdb_replacement_scan_info info, duckdb_value parameter);
DUCKDB_API void duckdb_replacement_scan_set_error(duckdb_replacement_scan_info info, const char *error);
DUCKDB_API duckdb_state duckdb_appender_create(duckdb_connection connection, const char *schema, const char *table,
duckdb_appender *out_appender);
DUCKDB_API const char *duckdb_appender_error(duckdb_appender appender);
DUCKDB_API duckdb_state duckdb_appender_flush(duckdb_appender appender);
DUCKDB_API duckdb_state duckdb_appender_close(duckdb_appender appender);
DUCKDB_API duckdb_state duckdb_appender_destroy(duckdb_appender *appender);
DUCKDB_API duckdb_state duckdb_appender_begin_row(duckdb_appender appender);
DUCKDB_API duckdb_state duckdb_appender_end_row(duckdb_appender appender);
DUCKDB_API duckdb_state duckdb_append_bool(duckdb_appender appender, bool value);
DUCKDB_API duckdb_state duckdb_append_int8(duckdb_appender appender, int8_t value);
DUCKDB_API duckdb_state duckdb_append_int16(duckdb_appender appender, int16_t value);
DUCKDB_API duckdb_state duckdb_append_int32(duckdb_appender appender, int32_t value);
DUCKDB_API duckdb_state duckdb_append_int64(duckdb_appender appender, int64_t value);
DUCKDB_API duckdb_state duckdb_append_hugeint(duckdb_appender appender, duckdb_hugeint value);
DUCKDB_API duckdb_state duckdb_append_uint8(duckdb_appender appender, uint8_t value);
DUCKDB_API duckdb_state duckdb_append_uint16(duckdb_appender appender, uint16_t value);
DUCKDB_API duckdb_state duckdb_append_uint32(duckdb_appender appender, uint32_t value);
DUCKDB_API duckdb_state duckdb_append_uint64(duckdb_appender appender, uint64_t value);
DUCKDB_API duckdb_state duckdb_append_float(duckdb_appender appender, float value);
DUCKDB_API duckdb_state duckdb_append_double(duckdb_appender appender, double value);
DUCKDB_API duckdb_state duckdb_append_date(duckdb_appender appender, duckdb_date value);
DUCKDB_API duckdb_state duckdb_append_time(duckdb_appender appender, duckdb_time value);
DUCKDB_API duckdb_state duckdb_append_timestamp(duckdb_appender appender, duckdb_timestamp value);
DUCKDB_API duckdb_state duckdb_append_interval(duckdb_appender appender, duckdb_interval value);
DUCKDB_API duckdb_state duckdb_append_varchar(duckdb_appender appender, const char *val);
DUCKDB_API duckdb_state duckdb_append_varchar_length(duckdb_appender appender, const char *val, idx_t length);
DUCKDB_API duckdb_state duckdb_append_blob(duckdb_appender appender, const void *data, idx_t length);
DUCKDB_API duckdb_state duckdb_append_null(duckdb_appender appender);
DUCKDB_API duckdb_state duckdb_append_data_chunk(duckdb_appender appender, duckdb_data_chunk chunk);
DUCKDB_API duckdb_state duckdb_query_arrow(duckdb_connection connection, const char *query, duckdb_arrow *out_result);
DUCKDB_API duckdb_state duckdb_query_arrow_schema(duckdb_arrow result, duckdb_arrow_schema *out_schema);
DUCKDB_API duckdb_state duckdb_query_arrow_array(duckdb_arrow result, duckdb_arrow_array *out_array);
DUCKDB_API idx_t duckdb_arrow_column_count(duckdb_arrow result);
DUCKDB_API idx_t duckdb_arrow_row_count(duckdb_arrow result);
DUCKDB_API idx_t duckdb_arrow_rows_changed(duckdb_arrow result);
DUCKDB_API const char *duckdb_query_arrow_error(duckdb_arrow result);
DUCKDB_API void duckdb_destroy_arrow(duckdb_arrow *result);
typedef void *duckdb_task_state;
DUCKDB_API void duckdb_execute_tasks(duckdb_database database, idx_t max_tasks);
DUCKDB_API duckdb_task_state duckdb_create_task_state(duckdb_database database);
DUCKDB_API void duckdb_execute_tasks_state(duckdb_task_state state);
DUCKDB_API idx_t duckdb_execute_n_tasks_state(duckdb_task_state state, idx_t max_tasks);
DUCKDB_API void duckdb_finish_execution(duckdb_task_state state);
DUCKDB_API bool duckdb_task_state_is_finished(duckdb_task_state state);
DUCKDB_API void duckdb_destroy_task_state(duckdb_task_state state);
DUCKDB_API bool duckdb_execution_is_finished(duckdb_connection con);
#ifdef __cplusplus
}
#endif
namespace duckdb {
template <typename T>
class BaseProfiler {
public:
void Start() {
finished = false;
start = Tick();
}
void End() {
end = Tick();
finished = true;
}
double Elapsed() const {
auto _end = finished ? end : Tick();
return std::chrono::duration_cast<std::chrono::duration<double>>(_end - start).count();
}
private:
time_point<T> Tick() const {
return T::now();
}
time_point<T> start;
time_point<T> end;
bool finished = false;
};
using Profiler = BaseProfiler<system_clock>;
}
namespace duckdb {
class ProgressBarDisplay {
public:
ProgressBarDisplay() {
}
virtual ~ProgressBarDisplay() {
}
public:
virtual void Update(double percentage) = 0;
virtual void Finish() = 0;
};
}
namespace duckdb {
typedef unique_ptr<ProgressBarDisplay> (*progress_bar_display_create_func_t)();
class ProgressBar {
public:
static unique_ptr<ProgressBarDisplay> DefaultProgressBarDisplay();
explicit ProgressBar(
Executor &executor, idx_t show_progress_after,
progress_bar_display_create_func_t create_display_func = ProgressBar::DefaultProgressBarDisplay);
void Start();
void Update(bool final);
double GetCurrentPercentage();
void PrintProgressInternal(int percentage);
void PrintProgress(int percentage);
void FinishProgressBarPrint();
bool ShouldPrint(bool final) const;
bool PrintEnabled() const;
private:
Executor &executor;
Profiler profiler;
idx_t show_progress_after;
double current_percentage;
unique_ptr<ProgressBarDisplay> display;
bool supported = true;
bool finished = false;
};
}
namespace duckdb {
class ClientContext;
class PhysicalResultCollector;
class PreparedStatementData;
typedef std::function<unique_ptr<PhysicalResultCollector>(ClientContext &context, PreparedStatementData &data)>
get_result_collector_t;
struct ClientConfig {
string home_directory;
bool enable_profiler = false;
bool enable_detailed_profiling = false;
ProfilerPrintFormat profiler_print_format = ProfilerPrintFormat::QUERY_TREE;
string profiler_save_location;
bool emit_profiler_output = true;
bool enable_progress_bar = false;
bool print_progress_bar = true;
int wait_time = 2000;
bool preserve_identifier_case = true;
idx_t max_expression_depth = 1000;
bool query_verification_enabled = false;
bool verify_external = false;
bool verify_serializer = false;
bool enable_optimizer = true;
bool verify_parallelism = false;
bool force_index_join = false;
bool force_external = false;
bool force_no_cross_product = false;
bool use_replacement_scans = true;
idx_t perfect_ht_threshold = 12;
progress_bar_display_create_func_t display_create_func = nullptr;
string custom_extension_repo = "";
ExplainOutputType explain_output_type = ExplainOutputType::PHYSICAL_ONLY;
case_insensitive_map_t<Value> set_variables;
get_result_collector_t result_collector = nullptr;
public:
static ClientConfig &GetConfig(ClientContext &context);
static const ClientConfig &GetConfig(const ClientContext &context);
static string ExtractTimezoneFromConfig(ClientConfig &config);
string ExtractTimezone() const;
bool AnyVerification() {
return query_verification_enabled || verify_external || verify_serializer;
}
};
}
namespace duckdb {
class Appender;
class Catalog;
class CatalogSearchPath;
class ColumnDataCollection;
class DatabaseInstance;
class FileOpener;
class LogicalOperator;
class PreparedStatementData;
class Relation;
class BufferedFileWriter;
class QueryProfiler;
class ClientContextLock;
struct CreateScalarFunctionInfo;
class ScalarFunctionCatalogEntry;
struct ActiveQueryContext;
struct ParserOptions;
struct ClientData;
struct PendingQueryParameters {
vector<Value> *parameters = nullptr;
bool allow_stream_result = false;
};
class ClientContextState {
public:
virtual ~ClientContextState() {};
virtual void QueryEnd() = 0;
};
class ClientContext : public std::enable_shared_from_this<ClientContext> {
friend class PendingQueryResult;
friend class StreamQueryResult;
friend class DuckTransactionManager;
public:
DUCKDB_API explicit ClientContext(shared_ptr<DatabaseInstance> db);
DUCKDB_API ~ClientContext();
shared_ptr<DatabaseInstance> db;
atomic<bool> interrupted;
unordered_map<string, vector<shared_ptr<ExternalDependency>>> external_dependencies;
unordered_map<string, shared_ptr<ClientContextState>> registered_state;
ClientConfig config;
unique_ptr<ClientData> client_data;
TransactionContext transaction;
public:
DUCKDB_API MetaTransaction &ActiveTransaction() {
return transaction.ActiveTransaction();
}
DUCKDB_API void Interrupt();
DUCKDB_API void EnableProfiling();
DUCKDB_API void DisableProfiling();
DUCKDB_API unique_ptr<QueryResult> Query(const string &query, bool allow_stream_result);
DUCKDB_API unique_ptr<QueryResult> Query(unique_ptr<SQLStatement> statement, bool allow_stream_result);
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(const string &query, bool allow_stream_result);
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(unique_ptr<SQLStatement> statement,
bool allow_stream_result);
DUCKDB_API void Destroy();
DUCKDB_API unique_ptr<TableDescription> TableInfo(const string &schema_name, const string &table_name);
DUCKDB_API void Append(TableDescription &description, ColumnDataCollection &collection);
DUCKDB_API void TryBindRelation(Relation &relation, vector<ColumnDefinition> &result_columns);
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(const shared_ptr<Relation> &relation,
bool allow_stream_result);
DUCKDB_API unique_ptr<QueryResult> Execute(const shared_ptr<Relation> &relation);
DUCKDB_API unique_ptr<PreparedStatement> Prepare(const string &query);
DUCKDB_API unique_ptr<PreparedStatement> Prepare(unique_ptr<SQLStatement> statement);
DUCKDB_API unique_ptr<PendingQueryResult>
PendingQuery(const string &query, shared_ptr<PreparedStatementData> &prepared, PendingQueryParameters parameters);
DUCKDB_API unique_ptr<QueryResult> Execute(const string &query, shared_ptr<PreparedStatementData> &prepared,
vector<Value> &values, bool allow_stream_result = true);
DUCKDB_API unique_ptr<QueryResult> Execute(const string &query, shared_ptr<PreparedStatementData> &prepared,
PendingQueryParameters parameters);
DUCKDB_API double GetProgress();
DUCKDB_API void RegisterFunction(CreateFunctionInfo *info);
DUCKDB_API vector<unique_ptr<SQLStatement>> ParseStatements(const string &query);
DUCKDB_API unique_ptr<LogicalOperator> ExtractPlan(const string &query);
DUCKDB_API void HandlePragmaStatements(vector<unique_ptr<SQLStatement>> &statements);
DUCKDB_API void RunFunctionInTransaction(const std::function<void(void)> &fun,
bool requires_valid_transaction = true);
DUCKDB_API void RunFunctionInTransactionInternal(ClientContextLock &lock, const std::function<void(void)> &fun,
bool requires_valid_transaction = true);
DUCKDB_API bool TryGetCurrentSetting(const std::string &key, Value &result);
DUCKDB_API ParserOptions GetParserOptions() const;
DUCKDB_API unique_ptr<DataChunk> Fetch(ClientContextLock &lock, StreamQueryResult &result);
DUCKDB_API bool IsActiveResult(ClientContextLock &lock, BaseQueryResult *result);
Executor &GetExecutor();
const string &GetCurrentQuery();
DUCKDB_API unordered_set<string> GetTableNames(const string &query);
DUCKDB_API ClientProperties GetClientProperties() const;
DUCKDB_API bool ExecutionIsFinished();
private:
bool ParseStatements(ClientContextLock &lock, const string &query, vector<unique_ptr<SQLStatement>> &result,
PreservedError &error);
unique_ptr<PendingQueryResult> PendingQueryInternal(ClientContextLock &lock, unique_ptr<SQLStatement> statement,
PendingQueryParameters parameters, bool verify = true);
unique_ptr<QueryResult> ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query);
vector<unique_ptr<SQLStatement>> ParseStatementsInternal(ClientContextLock &lock, const string &query);
PreservedError VerifyQuery(ClientContextLock &lock, const string &query, unique_ptr<SQLStatement> statement);
void InitialCleanup(ClientContextLock &lock);
void CleanupInternal(ClientContextLock &lock, BaseQueryResult *result = nullptr,
bool invalidate_transaction = false);
unique_ptr<PendingQueryResult> PendingStatementOrPreparedStatement(ClientContextLock &lock, const string &query,
unique_ptr<SQLStatement> statement,
shared_ptr<PreparedStatementData> &prepared,
PendingQueryParameters parameters);
unique_ptr<PendingQueryResult> PendingPreparedStatement(ClientContextLock &lock,
shared_ptr<PreparedStatementData> statement_p,
PendingQueryParameters parameters);
shared_ptr<PreparedStatementData> CreatePreparedStatement(ClientContextLock &lock, const string &query,
unique_ptr<SQLStatement> statement,
vector<Value> *values = nullptr);
unique_ptr<PendingQueryResult> PendingStatementInternal(ClientContextLock &lock, const string &query,
unique_ptr<SQLStatement> statement,
PendingQueryParameters parameters);
unique_ptr<QueryResult> RunStatementInternal(ClientContextLock &lock, const string &query,
unique_ptr<SQLStatement> statement, bool allow_stream_result,
bool verify = true);
unique_ptr<PreparedStatement> PrepareInternal(ClientContextLock &lock, unique_ptr<SQLStatement> statement);
void LogQueryInternal(ClientContextLock &lock, const string &query);
unique_ptr<QueryResult> FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending);
unique_ptr<DataChunk> FetchInternal(ClientContextLock &lock, Executor &executor, BaseQueryResult &result);
unique_ptr<ClientContextLock> LockContext();
void BeginTransactionInternal(ClientContextLock &lock, bool requires_valid_transaction);
void BeginQueryInternal(ClientContextLock &lock, const string &query);
PreservedError EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction);
PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock, PendingQueryResult &result);
unique_ptr<PendingQueryResult> PendingStatementOrPreparedStatementInternal(
ClientContextLock &lock, const string &query, unique_ptr<SQLStatement> statement,
shared_ptr<PreparedStatementData> &prepared, PendingQueryParameters parameters);
unique_ptr<PendingQueryResult> PendingQueryPreparedInternal(ClientContextLock &lock, const string &query,
shared_ptr<PreparedStatementData> &prepared,
PendingQueryParameters parameters);
unique_ptr<PendingQueryResult> PendingQueryInternal(ClientContextLock &, const shared_ptr<Relation> &relation,
bool allow_stream_result);
private:
mutex context_lock;
unique_ptr<ActiveQueryContext> active_query;
atomic<double> query_progress;
};
class ClientContextLock {
public:
explicit ClientContextLock(mutex &context_lock) : client_guard(context_lock) {
}
~ClientContextLock() {
}
private:
lock_guard<mutex> client_guard;
};
class ClientContextWrapper {
public:
DUCKDB_API explicit ClientContextWrapper(const shared_ptr<ClientContext> &context)
: client_context(context) {
};
shared_ptr<ClientContext> GetContext() {
auto actual_context = client_context.lock();
if (!actual_context) {
throw ConnectionException("Connection has already been closed");
}
return actual_context;
}
private:
std::weak_ptr<ClientContext> client_context;
};
}
#include <memory>
namespace duckdb {
struct BoundStatement;
class ClientContextWrapper;
class Binder;
class LogicalOperator;
class QueryNode;
class TableRef;
class Relation : public std::enable_shared_from_this<Relation> {
public:
DUCKDB_API Relation(const std::shared_ptr<ClientContext> &context, RelationType type)
: context(context), type(type) {
}
DUCKDB_API Relation(ClientContextWrapper &context, RelationType type) : context(context.GetContext()), type(type) {
}
DUCKDB_API virtual ~Relation() {
}
ClientContextWrapper context;
RelationType type;
shared_ptr<ExternalDependency> extra_dependencies;
public:
DUCKDB_API virtual const vector<ColumnDefinition> &Columns() = 0;
DUCKDB_API virtual unique_ptr<QueryNode> GetQueryNode();
DUCKDB_API virtual BoundStatement Bind(Binder &binder);
DUCKDB_API virtual string GetAlias();
DUCKDB_API unique_ptr<QueryResult> ExecuteOrThrow();
DUCKDB_API unique_ptr<QueryResult> Execute();
DUCKDB_API string ToString();
DUCKDB_API virtual string ToString(idx_t depth) = 0;
DUCKDB_API void Print();
DUCKDB_API void Head(idx_t limit = 10);
DUCKDB_API shared_ptr<Relation> CreateView(const string &name, bool replace = true, bool temporary = false);
DUCKDB_API shared_ptr<Relation> CreateView(const string &schema_name, const string &name, bool replace = true,
bool temporary = false);
DUCKDB_API unique_ptr<QueryResult> Query(const string &sql);
DUCKDB_API unique_ptr<QueryResult> Query(const string &name, const string &sql);
DUCKDB_API unique_ptr<QueryResult> Explain();
DUCKDB_API virtual unique_ptr<TableRef> GetTableRef();
DUCKDB_API virtual bool IsReadOnly() {
return true;
}
public:
DUCKDB_API shared_ptr<Relation> Project(const string &select_list);
DUCKDB_API shared_ptr<Relation> Project(const string &expression, const string &alias);
DUCKDB_API shared_ptr<Relation> Project(const string &select_list, const vector<string> &aliases);
DUCKDB_API shared_ptr<Relation> Project(const vector<string> &expressions);
DUCKDB_API shared_ptr<Relation> Project(const vector<string> &expressions, const vector<string> &aliases);
DUCKDB_API shared_ptr<Relation> Filter(const string &expression);
DUCKDB_API shared_ptr<Relation> Filter(const vector<string> &expressions);
DUCKDB_API shared_ptr<Relation> Limit(int64_t n, int64_t offset = 0);
DUCKDB_API shared_ptr<Relation> Order(const string &expression);
DUCKDB_API shared_ptr<Relation> Order(const vector<string> &expressions);
DUCKDB_API shared_ptr<Relation> Join(const shared_ptr<Relation> &other, const string &condition,
JoinType type = JoinType::INNER);
DUCKDB_API shared_ptr<Relation> CrossProduct(const shared_ptr<Relation> &other);
DUCKDB_API shared_ptr<Relation> Union(const shared_ptr<Relation> &other);
DUCKDB_API shared_ptr<Relation> Except(const shared_ptr<Relation> &other);
DUCKDB_API shared_ptr<Relation> Intersect(const shared_ptr<Relation> &other);
DUCKDB_API shared_ptr<Relation> Distinct();
DUCKDB_API shared_ptr<Relation> Aggregate(const string &aggregate_list);
DUCKDB_API shared_ptr<Relation> Aggregate(const vector<string> &aggregates);
DUCKDB_API shared_ptr<Relation> Aggregate(const string &aggregate_list, const string &group_list);
DUCKDB_API shared_ptr<Relation> Aggregate(const vector<string> &aggregates, const vector<string> &groups);
DUCKDB_API shared_ptr<Relation> Alias(const string &alias);
DUCKDB_API shared_ptr<Relation> InsertRel(const string &schema_name, const string &table_name);
DUCKDB_API void Insert(const string &table_name);
DUCKDB_API void Insert(const string &schema_name, const string &table_name);
DUCKDB_API void Insert(const vector<vector<Value>> &values);
DUCKDB_API shared_ptr<Relation> CreateRel(const string &schema_name, const string &table_name);
DUCKDB_API void Create(const string &table_name);
DUCKDB_API void Create(const string &schema_name, const string &table_name);
DUCKDB_API shared_ptr<Relation>
WriteCSVRel(const string &csv_file,
case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
DUCKDB_API void WriteCSV(const string &csv_file,
case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
DUCKDB_API shared_ptr<Relation>
WriteParquetRel(const string &parquet_file,
case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
DUCKDB_API void
WriteParquet(const string &parquet_file,
case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
DUCKDB_API virtual void Update(const string &update, const string &condition = string());
DUCKDB_API virtual void Delete(const string &condition = string());
DUCKDB_API shared_ptr<Relation> TableFunction(const std::string &fname, const vector<Value> &values);
DUCKDB_API shared_ptr<Relation> TableFunction(const std::string &fname, const vector<Value> &values,
const named_parameter_map_t &named_parameters);
public:
DUCKDB_API virtual bool InheritsColumnBindings() {
return false;
}
DUCKDB_API virtual Relation *ChildRelation() {
return nullptr;
}
DUCKDB_API vector<shared_ptr<ExternalDependency>> GetAllDependencies();
protected:
DUCKDB_API string RenderWhitespace(idx_t depth);
};
}
namespace duckdb {
enum class OutputStream : uint8_t { STREAM_STDOUT = 1, STREAM_STDERR = 2 };
class Printer {
public:
DUCKDB_API static void Print(OutputStream stream, const string &str);
DUCKDB_API static void Print(const string &str);
DUCKDB_API static void RawPrint(OutputStream stream, const string &str);
DUCKDB_API static void Flush(OutputStream stream);
DUCKDB_API static bool IsTerminal(OutputStream stream);
DUCKDB_API static idx_t TerminalWidth();
};
}
namespace duckdb {
class SQLStatement {
public:
explicit SQLStatement(StatementType type) : type(type) {};
virtual ~SQLStatement() {
}
StatementType type;
idx_t stmt_location = 0;
idx_t stmt_length = 0;
idx_t n_param = 0;
case_insensitive_map_t<idx_t> named_param_map;
string query;
protected:
SQLStatement(const SQLStatement &other) = default;
public:
DUCKDB_API virtual string ToString() const {
throw InternalException("ToString not supported for this type of SQLStatement: '%s'",
StatementTypeToString(type));
}
DUCKDB_API virtual unique_ptr<SQLStatement> Copy() const = 0;
};
}
namespace duckdb {
class ColumnDataCollection;
class ClientContext;
class DatabaseInstance;
class DuckDB;
class LogicalOperator;
class SelectStatement;
struct BufferedCSVReaderOptions;
typedef void (*warning_callback)(std::string);
class Connection {
public:
DUCKDB_API explicit Connection(DuckDB &database);
DUCKDB_API explicit Connection(DatabaseInstance &database);
DUCKDB_API ~Connection();
shared_ptr<ClientContext> context;
warning_callback warning_cb;
public:
DUCKDB_API string GetProfilingInformation(ProfilerPrintFormat format = ProfilerPrintFormat::QUERY_TREE);
DUCKDB_API void Interrupt();
DUCKDB_API void EnableProfiling();
DUCKDB_API void DisableProfiling();
DUCKDB_API void SetWarningCallback(warning_callback);
DUCKDB_API void EnableQueryVerification();
DUCKDB_API void DisableQueryVerification();
DUCKDB_API void ForceParallelism();
DUCKDB_API unique_ptr<QueryResult> SendQuery(const string &query);
DUCKDB_API unique_ptr<MaterializedQueryResult> Query(const string &query);
DUCKDB_API unique_ptr<MaterializedQueryResult> Query(unique_ptr<SQLStatement> statement);
template <typename... Args>
unique_ptr<QueryResult> Query(const string &query, Args... args) {
vector<Value> values;
return QueryParamsRecursive(query, values, args...);
}
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(const string &query, bool allow_stream_result = false);
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(unique_ptr<SQLStatement> statement,
bool allow_stream_result = false);
DUCKDB_API unique_ptr<PreparedStatement> Prepare(const string &query);
DUCKDB_API unique_ptr<PreparedStatement> Prepare(unique_ptr<SQLStatement> statement);
DUCKDB_API unique_ptr<TableDescription> TableInfo(const string &table_name);
DUCKDB_API unique_ptr<TableDescription> TableInfo(const string &schema_name, const string &table_name);
DUCKDB_API vector<unique_ptr<SQLStatement>> ExtractStatements(const string &query);
DUCKDB_API unique_ptr<LogicalOperator> ExtractPlan(const string &query);
DUCKDB_API void Append(TableDescription &description, DataChunk &chunk);
DUCKDB_API void Append(TableDescription &description, ColumnDataCollection &collection);
DUCKDB_API shared_ptr<Relation> Table(const string &tname);
DUCKDB_API shared_ptr<Relation> Table(const string &schema_name, const string &table_name);
DUCKDB_API shared_ptr<Relation> View(const string &tname);
DUCKDB_API shared_ptr<Relation> View(const string &schema_name, const string &table_name);
DUCKDB_API shared_ptr<Relation> TableFunction(const string &tname);
DUCKDB_API shared_ptr<Relation> TableFunction(const string &tname, const vector<Value> &values,
const named_parameter_map_t &named_parameters);
DUCKDB_API shared_ptr<Relation> TableFunction(const string &tname, const vector<Value> &values);
DUCKDB_API shared_ptr<Relation> Values(const vector<vector<Value>> &values);
DUCKDB_API shared_ptr<Relation> Values(const vector<vector<Value>> &values, const vector<string> &column_names,
const string &alias = "values");
DUCKDB_API shared_ptr<Relation> Values(const string &values);
DUCKDB_API shared_ptr<Relation> Values(const string &values, const vector<string> &column_names,
const string &alias = "values");
DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file);
DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file, BufferedCSVReaderOptions &options);
DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file, const vector<string> &columns);
DUCKDB_API shared_ptr<Relation> ReadParquet(const string &parquet_file, bool binary_as_string);
DUCKDB_API shared_ptr<Relation> RelationFromQuery(const string &query, const string &alias = "queryrelation",
const string &error = "Expected a single SELECT statement");
DUCKDB_API shared_ptr<Relation> RelationFromQuery(unique_ptr<SelectStatement> select_stmt,
const string &alias = "queryrelation");
DUCKDB_API string GetSubstrait(const string &query);
DUCKDB_API unique_ptr<QueryResult> FromSubstrait(const string &proto);
DUCKDB_API string GetSubstraitJSON(const string &query);
DUCKDB_API unique_ptr<QueryResult> FromSubstraitJSON(const string &json);
DUCKDB_API void BeginTransaction();
DUCKDB_API void Commit();
DUCKDB_API void Rollback();
DUCKDB_API void SetAutoCommit(bool auto_commit);
DUCKDB_API bool IsAutoCommit();
DUCKDB_API bool HasActiveTransaction();
DUCKDB_API unordered_set<string> GetTableNames(const string &query);
template <typename TR, typename... Args>
void CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) {
scalar_function_t function = UDFWrapper::CreateScalarFunction<TR, Args...>(name, udf_func);
UDFWrapper::RegisterFunction<TR, Args...>(name, function, *context);
}
template <typename TR, typename... Args>
void CreateScalarFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
TR (*udf_func)(Args...)) {
scalar_function_t function =
UDFWrapper::CreateScalarFunction<TR, Args...>(name, args, std::move(ret_type), udf_func);
UDFWrapper::RegisterFunction(name, args, ret_type, function, *context);
}
template <typename TR, typename... Args>
void CreateVectorizedFunction(const string &name, scalar_function_t udf_func,
LogicalType varargs = LogicalType::INVALID) {
UDFWrapper::RegisterFunction<TR, Args...>(name, udf_func, *context, std::move(varargs));
}
DUCKDB_API void CreateVectorizedFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
scalar_function_t udf_func, LogicalType varargs = LogicalType::INVALID) {
UDFWrapper::RegisterFunction(name, std::move(args), std::move(ret_type), udf_func, *context,
std::move(varargs));
}
template <typename UDF_OP, typename STATE, typename TR, typename TA>
void CreateAggregateFunction(const string &name) {
AggregateFunction function = UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA>(name);
UDFWrapper::RegisterAggrFunction(function, *context);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB>
void CreateAggregateFunction(const string &name) {
AggregateFunction function = UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA, TB>(name);
UDFWrapper::RegisterAggrFunction(function, *context);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA>
void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA) {
AggregateFunction function =
UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA>(name, ret_type, input_typeA);
UDFWrapper::RegisterAggrFunction(function, *context);
}
template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB>
void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA,
LogicalType input_typeB) {
AggregateFunction function =
UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA, TB>(name, ret_type, input_typeA, input_typeB);
UDFWrapper::RegisterAggrFunction(function, *context);
}
DUCKDB_API void CreateAggregateFunction(const string &name, vector<LogicalType> arguments, LogicalType return_type,
aggregate_size_t state_size, aggregate_initialize_t initialize,
aggregate_update_t update, aggregate_combine_t combine,
aggregate_finalize_t finalize,
aggregate_simple_update_t simple_update = nullptr,
bind_aggregate_function_t bind = nullptr,
aggregate_destructor_t destructor = nullptr) {
AggregateFunction function =
UDFWrapper::CreateAggregateFunction(name, arguments, return_type, state_size, initialize, update, combine,
finalize, simple_update, bind, destructor);
UDFWrapper::RegisterAggrFunction(function, *context);
}
private:
unique_ptr<QueryResult> QueryParamsRecursive(const string &query, vector<Value> &values);
template <typename T, typename... Args>
unique_ptr<QueryResult> QueryParamsRecursive(const string &query, vector<Value> &values, T value, Args... args) {
values.push_back(Value::CreateValue<T>(value));
return QueryParamsRecursive(query, values, args...);
}
};
}
namespace duckdb {
enum class AccessMode : uint8_t { UNDEFINED = 0, AUTOMATIC = 1, READ_ONLY = 2, READ_WRITE = 3 };
}
namespace duckdb {
enum class OptimizerType : uint32_t {
INVALID = 0,
EXPRESSION_REWRITER,
FILTER_PULLUP,
FILTER_PUSHDOWN,
REGEX_RANGE,
IN_CLAUSE,
JOIN_ORDER,
DELIMINATOR,
UNNEST_REWRITER,
UNUSED_COLUMNS,
STATISTICS_PROPAGATION,
COMMON_SUBEXPRESSIONS,
COMMON_AGGREGATE,
COLUMN_LIFETIME,
TOP_N,
REORDER_FILTER,
EXTENSION
};
string OptimizerTypeToString(OptimizerType type);
OptimizerType OptimizerTypeFromString(const string &str);
}
namespace duckdb {
enum class SetScope : uint8_t {
AUTOMATIC = 0,
LOCAL = 1,
SESSION = 2,
GLOBAL = 3
};
}
namespace duckdb {
enum class WindowAggregationMode : uint32_t {
WINDOW = 0,
COMBINE,
SEPARATE
};
}
namespace duckdb {
enum class BitpackingMode : uint8_t {
AUTO,
CONSTANT,
CONSTANT_DELTA,
DELTA_FOR,
FOR
};
BitpackingMode BitpackingModeFromString(const string &str);
string BitpackingModeToString(const BitpackingMode &mode);
}
namespace duckdb {
class CastFunctionSet;
struct FunctionLocalState;
struct BindCastInfo {
DUCKDB_API virtual ~BindCastInfo();
};
struct BoundCastData {
DUCKDB_API virtual ~BoundCastData();
DUCKDB_API virtual unique_ptr<BoundCastData> Copy() const = 0;
};
struct CastParameters {
CastParameters() {
}
CastParameters(BoundCastData *cast_data, bool strict, string *error_message, FunctionLocalState *local_state)
: cast_data(cast_data), strict(strict), error_message(error_message), local_state(local_state) {
}
CastParameters(CastParameters &parent, BoundCastData *cast_data = nullptr)
: cast_data(cast_data), strict(parent.strict), error_message(parent.error_message) {
}
BoundCastData *cast_data = nullptr;
bool strict = false;
string *error_message = nullptr;
FunctionLocalState *local_state = nullptr;
};
typedef bool (*cast_function_t)(Vector &source, Vector &result, idx_t count, CastParameters ¶meters);
typedef unique_ptr<FunctionLocalState> (*init_cast_local_state_t)(ClientContext &context);
struct BoundCastInfo {
DUCKDB_API
BoundCastInfo(
cast_function_t function, unique_ptr<BoundCastData> cast_data = nullptr,
init_cast_local_state_t init_local_state = nullptr); cast_function_t function;
init_cast_local_state_t init_local_state;
unique_ptr<BoundCastData> cast_data;
public:
BoundCastInfo Copy() const;
};
struct BindCastInput {
DUCKDB_API BindCastInput(CastFunctionSet &function_set, BindCastInfo *info, ClientContext *context);
CastFunctionSet &function_set;
BindCastInfo *info;
ClientContext *context;
public:
DUCKDB_API BoundCastInfo GetCastFunction(const LogicalType &source, const LogicalType &target);
};
struct ListBoundCastData : public BoundCastData {
explicit ListBoundCastData(BoundCastInfo child_cast) : child_cast_info(std::move(child_cast)) {
}
BoundCastInfo child_cast_info;
static unique_ptr<BoundCastData> BindListToListCast(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
public:
unique_ptr<BoundCastData> Copy() const override {
return make_unique<ListBoundCastData>(child_cast_info.Copy());
}
};
struct ListCast {
static bool ListToListCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters);
};
struct StructBoundCastData : public BoundCastData {
StructBoundCastData(vector<BoundCastInfo> child_casts, LogicalType target_p)
: child_cast_info(std::move(child_casts)), target(std::move(target_p)) {
}
vector<BoundCastInfo> child_cast_info;
LogicalType target;
static unique_ptr<BoundCastData> BindStructToStructCast(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
public:
unique_ptr<BoundCastData> Copy() const override {
vector<BoundCastInfo> copy_info;
for (auto &info : child_cast_info) {
copy_info.push_back(info.Copy());
}
return make_unique<StructBoundCastData>(std::move(copy_info), target);
}
};
struct MapBoundCastData : public BoundCastData {
MapBoundCastData(BoundCastInfo key_cast, BoundCastInfo value_cast)
: key_cast(std::move(key_cast)), value_cast(std::move(value_cast)) {
}
BoundCastInfo key_cast;
BoundCastInfo value_cast;
static unique_ptr<BoundCastData> BindMapToMapCast(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
public:
unique_ptr<BoundCastData> Copy() const override {
return make_unique<MapBoundCastData>(key_cast.Copy(), value_cast.Copy());
}
};
struct DefaultCasts {
DUCKDB_API static BoundCastInfo GetDefaultCastFunction(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
DUCKDB_API static bool NopCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters);
DUCKDB_API static bool TryVectorNullCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters);
DUCKDB_API static bool ReinterpretCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters);
private:
static BoundCastInfo BlobCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo BitCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo DateCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo DecimalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo EnumCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo IntervalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo ListCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo NumericCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo MapCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo PointerCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo StringCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo StructCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo TimeCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo TimeTzCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo TimestampCastSwitch(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
static BoundCastInfo TimestampTzCastSwitch(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
static BoundCastInfo TimestampNsCastSwitch(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
static BoundCastInfo TimestampMsCastSwitch(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
static BoundCastInfo TimestampSecCastSwitch(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
static BoundCastInfo UnionCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo UUIDCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
static BoundCastInfo ImplicitToUnionCast(BindCastInput &input, const LogicalType &source,
const LogicalType &target);
};
}
namespace duckdb {
class ClientContext;
class TableRef;
struct ReplacementScanData {
virtual ~ReplacementScanData() {
}
};
typedef unique_ptr<TableRef> (*replacement_scan_t)(ClientContext &context, const string &table_name,
ReplacementScanData *data);
struct ReplacementScan {
explicit ReplacementScan(replacement_scan_t function, unique_ptr<ReplacementScanData> data_p = nullptr)
: function(function), data(std::move(data_p)) {
}
replacement_scan_t function;
unique_ptr<ReplacementScanData> data;
};
}
#include <algorithm>
#include <functional>
namespace duckdb {
class FieldWriter;
class FieldReader;
extern const uint64_t PLAN_SERIALIZATION_VERSION;
class LogicalOperator {
public:
explicit LogicalOperator(LogicalOperatorType type);
LogicalOperator(LogicalOperatorType type, vector<unique_ptr<Expression>> expressions);
virtual ~LogicalOperator();
LogicalOperatorType type;
vector<unique_ptr<LogicalOperator>> children;
vector<unique_ptr<Expression>> expressions;
vector<LogicalType> types;
idx_t estimated_cardinality;
bool has_estimated_cardinality;
unique_ptr<EstimatedProperties> estimated_props;
public:
virtual vector<ColumnBinding> GetColumnBindings();
static vector<ColumnBinding> GenerateColumnBindings(idx_t table_idx, idx_t column_count);
static vector<LogicalType> MapTypes(const vector<LogicalType> &types, const vector<idx_t> &projection_map);
static vector<ColumnBinding> MapBindings(const vector<ColumnBinding> &types, const vector<idx_t> &projection_map);
void ResolveOperatorTypes();
virtual string GetName() const;
virtual string ParamsToString() const;
virtual string ToString() const;
DUCKDB_API void Print();
virtual void Verify(ClientContext &context);
void AddChild(unique_ptr<LogicalOperator> child);
virtual idx_t EstimateCardinality(ClientContext &context);
void Serialize(Serializer &serializer) const;
virtual void Serialize(FieldWriter &writer) const = 0;
static unique_ptr<LogicalOperator> Deserialize(Deserializer &deserializer, PlanDeserializationState &state);
virtual unique_ptr<LogicalOperator> Copy(ClientContext &context) const;
virtual bool RequireOptimizer() const {
return true;
}
virtual vector<idx_t> GetTableIndex() const;
protected:
virtual void ResolveTypes() = 0;
};
}
namespace duckdb {
struct OptimizerExtensionInfo {
DUCKDB_API virtual ~OptimizerExtensionInfo() {
}
};
typedef void (*optimize_function_t)(ClientContext &context, OptimizerExtensionInfo *info,
unique_ptr<LogicalOperator> &plan);
class OptimizerExtension {
public:
optimize_function_t optimize_function;
shared_ptr<OptimizerExtensionInfo> optimizer_info;
};
}
namespace duckdb {
struct ParserExtensionInfo {
DUCKDB_API virtual ~ParserExtensionInfo() {
}
};
enum class ParserExtensionResultType : uint8_t { PARSE_SUCCESSFUL, DISPLAY_ORIGINAL_ERROR, DISPLAY_EXTENSION_ERROR };
struct ParserExtensionParseData {
DUCKDB_API virtual ~ParserExtensionParseData() {
}
virtual unique_ptr<ParserExtensionParseData> Copy() const = 0;
};
struct ParserExtensionParseResult {
ParserExtensionParseResult() : type(ParserExtensionResultType::DISPLAY_ORIGINAL_ERROR) {
}
ParserExtensionParseResult(string error_p)
: type(ParserExtensionResultType::DISPLAY_EXTENSION_ERROR), error(std::move(error_p)) {
}
ParserExtensionParseResult(unique_ptr<ParserExtensionParseData> parse_data_p)
: type(ParserExtensionResultType::PARSE_SUCCESSFUL), parse_data(std::move(parse_data_p)) {
}
ParserExtensionResultType type;
unique_ptr<ParserExtensionParseData> parse_data;
string error;
};
typedef ParserExtensionParseResult (*parse_function_t)(ParserExtensionInfo *info, const string &query);
struct ParserExtensionPlanResult {
TableFunction function;
vector<Value> parameters;
unordered_set<string> modified_databases;
bool requires_valid_transaction = true;
StatementReturnType return_type = StatementReturnType::NOTHING;
};
typedef ParserExtensionPlanResult (*plan_function_t)(ParserExtensionInfo *info, ClientContext &context,
unique_ptr<ParserExtensionParseData> parse_data);
class ParserExtension {
public:
parse_function_t parse_function;
plan_function_t plan_function;
shared_ptr<ParserExtensionInfo> parser_info;
};
}
namespace duckdb {
class LogicalLimitPercent : public LogicalOperator {
public:
LogicalLimitPercent(double limit_percent, int64_t offset_val, unique_ptr<Expression> limit,
unique_ptr<Expression> offset)
: LogicalOperator(LogicalOperatorType::LOGICAL_LIMIT_PERCENT), limit_percent(limit_percent),
offset_val(offset_val), limit(std::move(limit)), offset(std::move(offset)) {
}
double limit_percent;
int64_t offset_val;
unique_ptr<Expression> limit;
unique_ptr<Expression> offset;
public:
vector<ColumnBinding> GetColumnBindings() override {
return children[0]->GetColumnBindings();
}
void Serialize(FieldWriter &writer) const override;
static unique_ptr<LogicalOperator> Deserialize(LogicalDeserializationState &state, FieldReader &reader);
idx_t EstimateCardinality(ClientContext &context) override;
protected:
void ResolveTypes() override {
types = children[0]->types;
}
};
}
namespace duckdb {
class CatalogEntry;
class DependencyList {
friend class DependencyManager;
public:
DUCKDB_API void AddDependency(CatalogEntry *entry);
private:
unordered_set<CatalogEntry *> set;
};
}
namespace duckdb {
class ClientContext;
class ColumnDataCollection;
class PhysicalPlanGenerator {
public:
explicit PhysicalPlanGenerator(ClientContext &context);
~PhysicalPlanGenerator();
DependencyList dependencies;
unordered_map<idx_t, std::shared_ptr<ColumnDataCollection>> recursive_cte_tables;
public:
unique_ptr<PhysicalOperator> CreatePlan(unique_ptr<LogicalOperator> logical);
static bool UseBatchIndex(ClientContext &context, PhysicalOperator &plan);
static bool PreserveInsertionOrder(ClientContext &context, PhysicalOperator &plan);
protected:
unique_ptr<PhysicalOperator> CreatePlan(LogicalOperator &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalAggregate &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalAnyJoin &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalColumnDataGet &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalComparisonJoin &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalCreate &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalCreateTable &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalCreateIndex &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalCrossProduct &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalDelete &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalDelimGet &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalDelimJoin &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalDistinct &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalDummyScan &expr);
unique_ptr<PhysicalOperator> CreatePlan(LogicalEmptyResult &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalExpressionGet &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalExport &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalFilter &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalGet &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalLimit &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalLimitPercent &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalOrder &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalTopN &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalPositionalJoin &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalProjection &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalInsert &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalCopyToFile &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalExplain &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalSetOperation &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalUpdate &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalPrepare &expr);
unique_ptr<PhysicalOperator> CreatePlan(LogicalWindow &expr);
unique_ptr<PhysicalOperator> CreatePlan(LogicalExecute &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalPragma &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalSample &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalSet &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalReset &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalShow &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalSimple &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalUnnest &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalRecursiveCTE &op);
unique_ptr<PhysicalOperator> CreatePlan(LogicalCTERef &op);
unique_ptr<PhysicalOperator> CreateDistinctOn(unique_ptr<PhysicalOperator> child,
vector<unique_ptr<Expression>> distinct_targets);
unique_ptr<PhysicalOperator> ExtractAggregateExpressions(unique_ptr<PhysicalOperator> child,
vector<unique_ptr<Expression>> &expressions,
vector<unique_ptr<Expression>> &groups);
private:
bool PreserveInsertionOrder(PhysicalOperator &plan);
bool UseBatchIndex(PhysicalOperator &plan);
private:
ClientContext &context;
};
}
namespace duckdb {
enum class TableReferenceType : uint8_t {
INVALID = 0, BASE_TABLE = 1, SUBQUERY = 2, JOIN = 3, TABLE_FUNCTION = 5, EXPRESSION_LIST = 6, CTE = 7, EMPTY = 8 };
}
namespace duckdb {
enum class SampleMethod : uint8_t { SYSTEM_SAMPLE = 0, BERNOULLI_SAMPLE = 1, RESERVOIR_SAMPLE = 2 };
string SampleMethodToString(SampleMethod method);
struct SampleOptions {
Value sample_size;
bool is_percentage;
SampleMethod method;
int64_t seed = -1;
unique_ptr<SampleOptions> Copy();
void Serialize(Serializer &serializer);
static unique_ptr<SampleOptions> Deserialize(Deserializer &source);
static bool Equals(SampleOptions *a, SampleOptions *b);
};
}
namespace duckdb {
class Deserializer;
class Serializer;
class TableRef {
public:
explicit TableRef(TableReferenceType type) : type(type) {
}
virtual ~TableRef() {
}
TableReferenceType type;
string alias;
unique_ptr<SampleOptions> sample;
idx_t query_location = DConstants::INVALID_INDEX;
public:
virtual string ToString() const = 0;
string BaseToString(string result) const;
string BaseToString(string result, const vector<string> &column_name_alias) const;
void Print();
virtual bool Equals(const TableRef *other) const;
virtual unique_ptr<TableRef> Copy() = 0;
DUCKDB_API void Serialize(Serializer &serializer) const;
DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0;
DUCKDB_API static unique_ptr<TableRef> Deserialize(Deserializer &source);
void CopyProperties(TableRef &target) const;
};
}
namespace duckdb {
class QueryNode;
class SelectStatement : public SQLStatement {
public:
DUCKDB_API SelectStatement() : SQLStatement(StatementType::SELECT_STATEMENT) {
}
unique_ptr<QueryNode> node;
protected:
SelectStatement(const SelectStatement &other);
public:
DUCKDB_API string ToString() const override;
DUCKDB_API unique_ptr<SQLStatement> Copy() const override;
void Serialize(Serializer &serializer) const;
static unique_ptr<SelectStatement> Deserialize(Deserializer &source);
bool Equals(const SQLStatement *other) const;
};
}
namespace duckdb {
class SelectStatement;
struct CommonTableExpressionInfo {
vector<string> aliases;
unique_ptr<SelectStatement> query;
};
}
namespace duckdb {
enum QueryNodeType : uint8_t {
SELECT_NODE = 1,
SET_OPERATION_NODE = 2,
BOUND_SUBQUERY_NODE = 3,
RECURSIVE_CTE_NODE = 4
};
struct CommonTableExpressionInfo;
class CommonTableExpressionMap {
public:
CommonTableExpressionMap();
unordered_map<string, unique_ptr<CommonTableExpressionInfo>> map;
public:
string ToString() const;
CommonTableExpressionMap Copy() const;
};
class QueryNode {
public:
explicit QueryNode(QueryNodeType type) : type(type) {
}
virtual ~QueryNode() {
}
QueryNodeType type;
vector<unique_ptr<ResultModifier>> modifiers;
CommonTableExpressionMap cte_map;
virtual const vector<unique_ptr<ParsedExpression>> &GetSelectList() const = 0;
public:
virtual string ToString() const = 0;
virtual bool Equals(const QueryNode *other) const;
virtual unique_ptr<QueryNode> Copy() const = 0;
DUCKDB_API void Serialize(Serializer &serializer) const;
DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0;
DUCKDB_API static unique_ptr<QueryNode> Deserialize(Deserializer &source);
string ResultModifiersToString() const;
void AddDistinct();
protected:
void CopyProperties(QueryNode &other) const;
};
}
namespace duckdb {
class SQLStatement;
class AlterStatement;
class AttachStatement;
class CallStatement;
class CopyStatement;
class CreateStatement;
class DetachStatement;
class DeleteStatement;
class DropStatement;
class ExtensionStatement;
class InsertStatement;
class SelectStatement;
class TransactionStatement;
class UpdateStatement;
class PrepareStatement;
class ExecuteStatement;
class PragmaStatement;
class ShowStatement;
class ExplainStatement;
class ExportStatement;
class VacuumStatement;
class RelationStatement;
class SetStatement;
class SetVariableStatement;
class ResetVariableStatement;
class LoadStatement;
class LogicalPlanStatement;
class QueryNode;
class SelectNode;
class SetOperationNode;
class RecursiveCTENode;
class ParsedExpression;
class BetweenExpression;
class CaseExpression;
class CastExpression;
class CollateExpression;
class ColumnRefExpression;
class ComparisonExpression;
class ConjunctionExpression;
class ConstantExpression;
class DefaultExpression;
class FunctionExpression;
class LambdaExpression;
class OperatorExpression;
class ParameterExpression;
class PositionalReferenceExpression;
class StarExpression;
class SubqueryExpression;
class WindowExpression;
class Constraint;
class NotNullConstraint;
class CheckConstraint;
class UniqueConstraint;
class ForeignKeyConstraint;
class TableRef;
class BaseTableRef;
class JoinRef;
class SubqueryRef;
class TableFunctionRef;
class EmptyTableRef;
class ExpressionListRef;
struct SampleOptions;
}
namespace duckdb {
class ColumnRefExpression : public ParsedExpression {
public:
ColumnRefExpression(string column_name, string table_name);
explicit ColumnRefExpression(string column_name);
explicit ColumnRefExpression(vector<string> column_names);
vector<string> column_names;
public:
bool IsQualified() const;
const string &GetColumnName() const;
const string &GetTableName() const;
bool IsScalar() const override {
return false;
}
string GetName() const override;
string ToString() const override;
static bool Equal(const ColumnRefExpression *a, const ColumnRefExpression *b);
hash_t Hash() const override;
unique_ptr<ParsedExpression> Copy() const override;
void Serialize(FieldWriter &writer) const override;
static unique_ptr<ParsedExpression> Deserialize(ExpressionType type, FieldReader &source);
};
}
namespace duckdb {
struct string_t;
struct interval_t;
inline hash_t murmurhash64(uint64_t x) {
x ^= x >> 32;
x *= 0xd6e8feb86659fd93U;
x ^= x >> 32;
x *= 0xd6e8feb86659fd93U;
x ^= x >> 32;
return x;
}
inline hash_t murmurhash32(uint32_t x) {
return murmurhash64(x);
}
template <class T>
hash_t Hash(T value) {
return murmurhash32(value);
}
inline hash_t CombineHash(hash_t left, hash_t right) {
return left ^ right;
}
template <>
DUCKDB_API hash_t Hash(uint64_t val);
template <>
DUCKDB_API hash_t Hash(int64_t val);
template <>
DUCKDB_API hash_t Hash(hugeint_t val);
template <>
DUCKDB_API hash_t Hash(float val);
template <>
DUCKDB_API hash_t Hash(double val);
template <>
DUCKDB_API hash_t Hash(const char *val);
template <>
DUCKDB_API hash_t Hash(char *val);
template <>
DUCKDB_API hash_t Hash(string_t val);
template <>
DUCKDB_API hash_t Hash(interval_t val);
DUCKDB_API hash_t Hash(const char *val, size_t size);
DUCKDB_API hash_t Hash(uint8_t *val, size_t size);
}
namespace duckdb {
struct QualifiedColumnHashFunction {
uint64_t operator()(const QualifiedColumnName &a) const {
std::hash<std::string> str_hasher;
return str_hasher(a.schema) ^ str_hasher(a.table) ^ str_hasher(a.column);
}
};
struct QualifiedColumnEquality {
bool operator()(const QualifiedColumnName &a, const QualifiedColumnName &b) const {
return a.schema == b.schema && a.table == b.table && a.column == b.column;
}
};
using qualified_column_set_t = unordered_set<QualifiedColumnName, QualifiedColumnHashFunction, QualifiedColumnEquality>;
}
namespace duckdb {
class BoundExpression : public ParsedExpression {
public:
BoundExpression(unique_ptr<Expression> expr);
unique_ptr<Expression> expr;
public:
string ToString() const override;
bool Equals(const BaseExpression *other) const override;
hash_t Hash() const override;
unique_ptr<ParsedExpression> Copy() const override;
void Serialize(FieldWriter &writer) const override;
};
}
namespace duckdb {
class Binder;
class ClientContext;
class QueryNode;
class ScalarFunctionCatalogEntry;
class AggregateFunctionCatalogEntry;
class ScalarMacroCatalogEntry;
class CatalogEntry;
class SimpleFunction;
struct DummyBinding;
struct BoundColumnReferenceInfo {
string name;
idx_t query_location;
};
struct BindResult {
BindResult() {
}
explicit BindResult(string error) : error(error) {
}
explicit BindResult(unique_ptr<Expression> expr) : expression(std::move(expr)) {
}
bool HasError() {
return !error.empty();
}
unique_ptr<Expression> expression;
string error;
};
class ExpressionBinder {
public:
ExpressionBinder(Binder &binder, ClientContext &context, bool replace_binder = false);
virtual ~ExpressionBinder();
LogicalType target_type;
DummyBinding *macro_binding;
vector<DummyBinding> *lambda_bindings = nullptr;
public:
unique_ptr<Expression> Bind(unique_ptr<ParsedExpression> &expr, LogicalType *result_type = nullptr,
bool root_expression = true);
bool HasBoundColumns() {
return !bound_columns.empty();
}
const vector<BoundColumnReferenceInfo> &GetBoundColumns() {
return bound_columns;
}
string Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, bool root_expression = false);
unique_ptr<ParsedExpression> CreateStructExtract(unique_ptr<ParsedExpression> base, string field_name);
unique_ptr<ParsedExpression> CreateStructPack(ColumnRefExpression &colref);
BindResult BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name);
unique_ptr<ParsedExpression> QualifyColumnName(const string &column_name, string &error_message);
unique_ptr<ParsedExpression> QualifyColumnName(ColumnRefExpression &colref, string &error_message);
void QualifyColumnNames(unique_ptr<ParsedExpression> &expr);
static void QualifyColumnNames(Binder &binder, unique_ptr<ParsedExpression> &expr);
static unique_ptr<Expression> PushCollation(ClientContext &context, unique_ptr<Expression> source,
const string &collation, bool equality_only = false);
static void TestCollation(ClientContext &context, const string &collation);
bool BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr);
void BindChild(unique_ptr<ParsedExpression> &expr, idx_t depth, string &error);
static void ExtractCorrelatedExpressions(Binder &binder, Expression &expr);
static bool ContainsNullType(const LogicalType &type);
static LogicalType ExchangeNullType(const LogicalType &type);
static bool ContainsType(const LogicalType &type, LogicalTypeId target);
static LogicalType ExchangeType(const LogicalType &type, LogicalTypeId target, LogicalType new_type);
virtual BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
bool root_expression = false);
void ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr);
protected:
BindResult BindExpression(BetweenExpression &expr, idx_t depth);
BindResult BindExpression(CaseExpression &expr, idx_t depth);
BindResult BindExpression(CollateExpression &expr, idx_t depth);
BindResult BindExpression(CastExpression &expr, idx_t depth);
BindResult BindExpression(ColumnRefExpression &expr, idx_t depth);
BindResult BindExpression(ComparisonExpression &expr, idx_t depth);
BindResult BindExpression(ConjunctionExpression &expr, idx_t depth);
BindResult BindExpression(ConstantExpression &expr, idx_t depth);
BindResult BindExpression(FunctionExpression &expr, idx_t depth, unique_ptr<ParsedExpression> *expr_ptr);
BindResult BindExpression(LambdaExpression &expr, idx_t depth, const bool is_lambda,
const LogicalType &list_child_type);
BindResult BindExpression(OperatorExpression &expr, idx_t depth);
BindResult BindExpression(ParameterExpression &expr, idx_t depth);
BindResult BindExpression(PositionalReferenceExpression &ref, idx_t depth);
BindResult BindExpression(SubqueryExpression &expr, idx_t depth);
void TransformCapturedLambdaColumn(unique_ptr<Expression> &original, unique_ptr<Expression> &replacement,
vector<unique_ptr<Expression>> &captures, LogicalType &list_child_type);
void CaptureLambdaColumns(vector<unique_ptr<Expression>> &captures, LogicalType &list_child_type,
unique_ptr<Expression> &expr);
protected:
virtual BindResult BindGroupingFunction(OperatorExpression &op, idx_t depth);
virtual BindResult BindFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry *function, idx_t depth);
virtual BindResult BindLambdaFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry *function, idx_t depth);
virtual BindResult BindAggregate(FunctionExpression &expr, AggregateFunctionCatalogEntry *function, idx_t depth);
virtual BindResult BindUnnest(FunctionExpression &expr, idx_t depth);
virtual BindResult BindMacro(FunctionExpression &expr, ScalarMacroCatalogEntry *macro, idx_t depth,
unique_ptr<ParsedExpression> *expr_ptr);
virtual string UnsupportedAggregateMessage();
virtual string UnsupportedUnnestMessage();
Binder &binder;
ClientContext &context;
ExpressionBinder *stored_binder;
vector<BoundColumnReferenceInfo> bound_columns;
};
}
namespace duckdb {
class BindContext;
class BoundQueryNode;
class ColumnRefExpression;
class SubqueryRef;
class LogicalGet;
class TableCatalogEntry;
class TableFunctionCatalogEntry;
class BoundTableFunction;
class StandardEntry;
struct ColumnBinding;
enum class BindingType { BASE, TABLE, DUMMY, CATALOG_ENTRY };
struct Binding {
Binding(BindingType binding_type, const string &alias, vector<LogicalType> types, vector<string> names,
idx_t index);
virtual ~Binding() = default;
BindingType binding_type;
string alias;
idx_t index;
vector<LogicalType> types;
vector<string> names;
case_insensitive_map_t<column_t> name_map;
public:
bool TryGetBindingIndex(const string &column_name, column_t &column_index);
column_t GetBindingIndex(const string &column_name);
bool HasMatchingBinding(const string &column_name);
virtual string ColumnNotFoundError(const string &column_name) const;
virtual BindResult Bind(ColumnRefExpression &colref, idx_t depth);
virtual StandardEntry *GetStandardEntry();
};
struct EntryBinding : public Binding {
public:
EntryBinding(const string &alias, vector<LogicalType> types, vector<string> names, idx_t index,
StandardEntry &entry);
StandardEntry &entry;
public:
StandardEntry *GetStandardEntry() override;
};
struct TableBinding : public Binding {
TableBinding(const string &alias, vector<LogicalType> types, vector<string> names,
vector<column_t> &bound_column_ids, StandardEntry *entry, idx_t index, bool add_row_id = false);
vector<column_t> &bound_column_ids;
StandardEntry *entry;
public:
unique_ptr<ParsedExpression> ExpandGeneratedColumn(const string &column_name);
BindResult Bind(ColumnRefExpression &colref, idx_t depth) override;
StandardEntry *GetStandardEntry() override;
string ColumnNotFoundError(const string &column_name) const override;
const vector<column_t> &GetBoundColumnIds() const;
protected:
ColumnBinding GetColumnBinding(column_t column_index);
};
struct DummyBinding : public Binding {
static constexpr const char *DUMMY_NAME = "0_macro_parameters";
public:
DummyBinding(vector<LogicalType> types_p, vector<string> names_p, string dummy_name_p);
vector<unique_ptr<ParsedExpression>> *arguments;
string dummy_name;
public:
BindResult Bind(ColumnRefExpression &colref, idx_t depth) override;
BindResult Bind(ColumnRefExpression &colref, idx_t lambda_index, idx_t depth);
unique_ptr<ParsedExpression> ParamToArg(ColumnRefExpression &colref);
};
}
namespace duckdb {
class Binder;
class LogicalGet;
class BoundQueryNode;
class StarExpression;
class TableCatalogEntry;
class TableFunctionCatalogEntry;
struct UsingColumnSet {
string primary_binding;
unordered_set<string> bindings;
};
class BindContext {
public:
case_insensitive_map_t<std::shared_ptr<idx_t>> cte_references;
public:
string GetMatchingBinding(const string &column_name);
unordered_set<string> GetMatchingBindings(const string &column_name);
vector<string> GetSimilarBindings(const string &column_name);
Binding *GetCTEBinding(const string &ctename);
BindResult BindColumn(ColumnRefExpression &colref, idx_t depth);
string BindColumn(PositionalReferenceExpression &ref, string &table_name, string &column_name);
BindResult BindColumn(PositionalReferenceExpression &ref, idx_t depth);
unique_ptr<ParsedExpression> ExpandGeneratedColumn(const string &table_name, const string &column_name);
unique_ptr<ParsedExpression> CreateColumnReference(const string &table_name, const string &column_name);
unique_ptr<ParsedExpression> CreateColumnReference(const string &schema_name, const string &table_name,
const string &column_name);
unique_ptr<ParsedExpression> CreateColumnReference(const string &catalog_name, const string &schema_name,
const string &table_name, const string &column_name);
void GenerateAllColumnExpressions(StarExpression &expr, vector<unique_ptr<ParsedExpression>> &new_select_list);
bool CheckExclusionList(StarExpression &expr, Binding *binding, const string &column_name,
vector<unique_ptr<ParsedExpression>> &new_select_list,
case_insensitive_set_t &excluded_columns);
const vector<std::pair<string, Binding *>> &GetBindingsList() {
return bindings_list;
}
void AddBaseTable(idx_t index, const string &alias, const vector<string> &names, const vector<LogicalType> &types,
vector<column_t> &bound_column_ids, StandardEntry *entry, bool add_row_id = true);
void AddTableFunction(idx_t index, const string &alias, const vector<string> &names,
const vector<LogicalType> &types, vector<column_t> &bound_column_ids, StandardEntry *entry);
void AddView(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery, ViewCatalogEntry *view);
void AddSubquery(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery);
void AddSubquery(idx_t index, const string &alias, TableFunctionRef &ref, BoundQueryNode &subquery);
void AddEntryBinding(idx_t index, const string &alias, const vector<string> &names,
const vector<LogicalType> &types, StandardEntry *entry);
void AddGenericBinding(idx_t index, const string &alias, const vector<string> &names,
const vector<LogicalType> &types);
void AddCTEBinding(idx_t index, const string &alias, const vector<string> &names, const vector<LogicalType> &types);
void AddUsingBinding(const string &column_name, UsingColumnSet *set);
void AddUsingBindingSet(unique_ptr<UsingColumnSet> set);
UsingColumnSet *GetUsingBinding(const string &column_name);
UsingColumnSet *GetUsingBinding(const string &column_name, const string &binding_name);
void RemoveUsingBinding(const string &column_name, UsingColumnSet *set);
bool FindUsingBinding(const string &column_name, unordered_set<UsingColumnSet *> **using_columns);
void TransferUsingBinding(BindContext ¤t_context, UsingColumnSet *current_set, UsingColumnSet *new_set,
const string &binding, const string &using_column);
string GetActualColumnName(const string &binding, const string &column_name);
case_insensitive_map_t<std::shared_ptr<Binding>> GetCTEBindings() {
return cte_bindings;
}
void SetCTEBindings(case_insensitive_map_t<std::shared_ptr<Binding>> bindings) {
cte_bindings = bindings;
}
static vector<string> AliasColumnNames(const string &table_name, const vector<string> &names,
const vector<string> &column_aliases);
void AddContext(BindContext other);
Binding *GetBinding(const string &name, string &out_error);
private:
void AddBinding(const string &alias, unique_ptr<Binding> binding);
private:
case_insensitive_map_t<unique_ptr<Binding>> bindings;
vector<std::pair<string, Binding *>> bindings_list;
case_insensitive_map_t<unordered_set<UsingColumnSet *>> using_columns;
vector<unique_ptr<UsingColumnSet>> using_column_sets;
case_insensitive_map_t<std::shared_ptr<Binding>> cte_bindings;
};
}
namespace duckdb {
class FieldReader;
class FieldWriter;
class BoundColumnRefExpression : public Expression {
public:
BoundColumnRefExpression(LogicalType type, ColumnBinding binding, idx_t depth = 0);
BoundColumnRefExpression(string alias, LogicalType type, ColumnBinding binding, idx_t depth = 0);
ColumnBinding binding;
idx_t depth;
public:
bool IsScalar() const override {
return false;
}
bool IsFoldable() const override {
return false;
}
string ToString() const override;
bool Equals(const BaseExpression *other) const override;
hash_t Hash() const override;
unique_ptr<Expression> Copy() override;
void Serialize(FieldWriter &writer) const override;
static unique_ptr<Expression> Deserialize(ExpressionDeserializationState &state, FieldReader &reader);
};
}
namespace duckdb {
class BoundResultModifier;
class BoundSelectNode;
class ClientContext;
class ExpressionBinder;
class LimitModifier;
class OrderBinder;
class TableCatalogEntry;
class ViewCatalogEntry;
class TableMacroCatalogEntry;
class UpdateSetInfo;
class LogicalProjection;
class ColumnList;
class ExternalDependency;
class TableFunction;
struct CreateInfo;
struct BoundCreateTableInfo;
struct BoundCreateFunctionInfo;
struct CommonTableExpressionInfo;
struct BoundParameterMap;
enum class BindingMode : uint8_t { STANDARD_BINDING, EXTRACT_NAMES };
struct CorrelatedColumnInfo {
ColumnBinding binding;
LogicalType type;
string name;
idx_t depth;
CorrelatedColumnInfo(ColumnBinding binding, LogicalType type_p, string name_p, idx_t depth)
: binding(binding), type(std::move(type_p)), name(std::move(name_p)), depth(depth) {
}
explicit CorrelatedColumnInfo(BoundColumnRefExpression &expr)
: CorrelatedColumnInfo(expr.binding, expr.return_type, expr.GetName(), expr.depth) {
}
bool operator==(const CorrelatedColumnInfo &rhs) const {
return binding == rhs.binding;
}
};
class Binder : public std::enable_shared_from_this<Binder> {
friend class ExpressionBinder;
friend class SelectBinder;
friend class RecursiveSubqueryPlanner;
public:
DUCKDB_API static shared_ptr<Binder> CreateBinder(ClientContext &context, Binder *parent = nullptr,
bool inherit_ctes = true);
ClientContext &context;
case_insensitive_map_t<CommonTableExpressionInfo *> CTE_bindings; unordered_set<CommonTableExpressionInfo *> bound_ctes;
BindContext bind_context;
vector<CorrelatedColumnInfo> correlated_columns;
BoundParameterMap *parameters;
StatementProperties properties;
string alias;
DummyBinding *macro_binding = nullptr;
vector<DummyBinding> *lambda_bindings = nullptr;
public:
DUCKDB_API BoundStatement Bind(SQLStatement &statement);
DUCKDB_API BoundStatement Bind(QueryNode &node);
unique_ptr<BoundCreateTableInfo> BindCreateTableInfo(unique_ptr<CreateInfo> info);
unique_ptr<BoundCreateTableInfo> BindCreateTableInfo(unique_ptr<CreateInfo> info, SchemaCatalogEntry *schema);
vector<unique_ptr<Expression>> BindCreateIndexExpressions(TableCatalogEntry *table, CreateIndexInfo *info);
void BindCreateViewInfo(CreateViewInfo &base);
SchemaCatalogEntry *BindSchema(CreateInfo &info);
SchemaCatalogEntry *BindCreateFunctionInfo(CreateInfo &info);
static void BindNamedParameters(named_parameter_type_map_t &types, named_parameter_map_t &values,
QueryErrorContext &error_context, string &func_name);
unique_ptr<BoundTableRef> Bind(TableRef &ref);
unique_ptr<LogicalOperator> CreatePlan(BoundTableRef &ref);
idx_t GenerateTableIndex();
void AddCTE(const string &name, CommonTableExpressionInfo *cte);
CommonTableExpressionInfo *FindCTE(const string &name, bool skip = false);
bool CTEIsAlreadyBound(CommonTableExpressionInfo *cte);
void AddBoundView(ViewCatalogEntry *view);
void PushExpressionBinder(ExpressionBinder *binder);
void PopExpressionBinder();
void SetActiveBinder(ExpressionBinder *binder);
ExpressionBinder *GetActiveBinder();
bool HasActiveBinder();
vector<ExpressionBinder *> &GetActiveBinders();
void MergeCorrelatedColumns(vector<CorrelatedColumnInfo> &other);
void AddCorrelatedColumn(const CorrelatedColumnInfo &info);
string FormatError(ParsedExpression &expr_context, const string &message);
string FormatError(TableRef &ref_context, const string &message);
string FormatErrorRecursive(idx_t query_location, const string &message, vector<ExceptionFormatValue> &values);
template <class T, typename... ARGS>
string FormatErrorRecursive(idx_t query_location, const string &msg, vector<ExceptionFormatValue> &values, T param,
ARGS... params) {
values.push_back(ExceptionFormatValue::CreateFormatValue<T>(param));
return FormatErrorRecursive(query_location, msg, values, params...);
}
template <typename... ARGS>
string FormatError(idx_t query_location, const string &msg, ARGS... params) {
vector<ExceptionFormatValue> values;
return FormatErrorRecursive(query_location, msg, values, params...);
}
unique_ptr<LogicalOperator> BindUpdateSet(LogicalOperator *op, unique_ptr<LogicalOperator> root,
UpdateSetInfo &set_info, TableCatalogEntry *table,
vector<PhysicalIndex> &columns);
void BindDoUpdateSetExpressions(const string &table_alias, LogicalInsert *insert, UpdateSetInfo &set_info,
TableCatalogEntry &table);
void BindOnConflictClause(LogicalInsert &insert, TableCatalogEntry &table, InsertStatement &stmt);
static void BindSchemaOrCatalog(ClientContext &context, string &catalog, string &schema);
static void BindLogicalType(ClientContext &context, LogicalType &type, Catalog *catalog = nullptr,
const string &schema = INVALID_SCHEMA);
bool HasMatchingBinding(const string &table_name, const string &column_name, string &error_message);
bool HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name,
string &error_message);
bool HasMatchingBinding(const string &catalog_name, const string &schema_name, const string &table_name,
const string &column_name, string &error_message);
void SetBindingMode(BindingMode mode);
BindingMode GetBindingMode();
void AddTableName(string table_name);
const unordered_set<string> &GetTableNames();
void SetCanContainNulls(bool can_contain_nulls);
private:
shared_ptr<Binder> parent;
vector<ExpressionBinder *> active_binders;
idx_t bound_tables;
bool has_unplanned_subqueries = false;
bool plan_subquery = true;
bool inherit_ctes = true;
bool can_contain_nulls = false;
SQLStatement *root_statement = nullptr;
BindingMode mode = BindingMode::STANDARD_BINDING;
unordered_set<string> table_names;
unordered_set<ViewCatalogEntry *> bound_views;
private:
void BindGeneratedColumns(BoundCreateTableInfo &info);
void BindDefaultValues(const ColumnList &columns, vector<unique_ptr<Expression>> &bound_defaults);
unique_ptr<Expression> BindDelimiter(ClientContext &context, OrderBinder &order_binder,
unique_ptr<ParsedExpression> delimiter, const LogicalType &type,
Value &delimiter_value);
void MoveCorrelatedExpressions(Binder &other);
BoundStatement Bind(SelectStatement &stmt);
BoundStatement Bind(InsertStatement &stmt);
BoundStatement Bind(CopyStatement &stmt);
BoundStatement Bind(DeleteStatement &stmt);
BoundStatement Bind(UpdateStatement &stmt);
BoundStatement Bind(CreateStatement &stmt);
BoundStatement Bind(DropStatement &stmt);
BoundStatement Bind(AlterStatement &stmt);
BoundStatement Bind(PrepareStatement &stmt);
BoundStatement Bind(ExecuteStatement &stmt);
BoundStatement Bind(TransactionStatement &stmt);
BoundStatement Bind(PragmaStatement &stmt);
BoundStatement Bind(ExplainStatement &stmt);
BoundStatement Bind(VacuumStatement &stmt);
BoundStatement Bind(RelationStatement &stmt);
BoundStatement Bind(ShowStatement &stmt);
BoundStatement Bind(CallStatement &stmt);
BoundStatement Bind(ExportStatement &stmt);
BoundStatement Bind(ExtensionStatement &stmt);
BoundStatement Bind(SetStatement &stmt);
BoundStatement Bind(SetVariableStatement &stmt);
BoundStatement Bind(ResetVariableStatement &stmt);
BoundStatement Bind(LoadStatement &stmt);
BoundStatement Bind(LogicalPlanStatement &stmt);
BoundStatement Bind(AttachStatement &stmt);
BoundStatement Bind(DetachStatement &stmt);
BoundStatement BindReturning(vector<unique_ptr<ParsedExpression>> returning_list, TableCatalogEntry *table,
idx_t update_table_index, unique_ptr<LogicalOperator> child_operator,
BoundStatement result);
unique_ptr<QueryNode> BindTableMacro(FunctionExpression &function, TableMacroCatalogEntry *macro_func, idx_t depth);
unique_ptr<BoundQueryNode> BindNode(SelectNode &node);
unique_ptr<BoundQueryNode> BindNode(SetOperationNode &node);
unique_ptr<BoundQueryNode> BindNode(RecursiveCTENode &node);
unique_ptr<BoundQueryNode> BindNode(QueryNode &node);
unique_ptr<LogicalOperator> VisitQueryNode(BoundQueryNode &node, unique_ptr<LogicalOperator> root);
unique_ptr<LogicalOperator> CreatePlan(BoundRecursiveCTENode &node);
unique_ptr<LogicalOperator> CreatePlan(BoundSelectNode &statement);
unique_ptr<LogicalOperator> CreatePlan(BoundSetOperationNode &node);
unique_ptr<LogicalOperator> CreatePlan(BoundQueryNode &node);
unique_ptr<BoundTableRef> Bind(BaseTableRef &ref);
unique_ptr<BoundTableRef> Bind(JoinRef &ref);
unique_ptr<BoundTableRef> Bind(SubqueryRef &ref, CommonTableExpressionInfo *cte = nullptr);
unique_ptr<BoundTableRef> Bind(TableFunctionRef &ref);
unique_ptr<BoundTableRef> Bind(EmptyTableRef &ref);
unique_ptr<BoundTableRef> Bind(ExpressionListRef &ref);
bool BindTableFunctionParameters(TableFunctionCatalogEntry &table_function,
vector<unique_ptr<ParsedExpression>> &expressions, vector<LogicalType> &arguments,
vector<Value> ¶meters, named_parameter_map_t &named_parameters,
unique_ptr<BoundSubqueryRef> &subquery, string &error);
bool BindTableInTableOutFunction(vector<unique_ptr<ParsedExpression>> &expressions,
unique_ptr<BoundSubqueryRef> &subquery, string &error);
unique_ptr<LogicalOperator> BindTableFunction(TableFunction &function, vector<Value> parameters);
unique_ptr<LogicalOperator>
BindTableFunctionInternal(TableFunction &table_function, const string &function_name, vector<Value> parameters,
named_parameter_map_t named_parameters, vector<LogicalType> input_table_types,
vector<string> input_table_names, const vector<string> &column_name_alias,
unique_ptr<ExternalDependency> external_dependency);
unique_ptr<LogicalOperator> CreatePlan(BoundBaseTableRef &ref);
unique_ptr<LogicalOperator> CreatePlan(BoundJoinRef &ref);
unique_ptr<LogicalOperator> CreatePlan(BoundSubqueryRef &ref);
unique_ptr<LogicalOperator> CreatePlan(BoundTableFunction &ref);
unique_ptr<LogicalOperator> CreatePlan(BoundEmptyTableRef &ref);
unique_ptr<LogicalOperator> CreatePlan(BoundExpressionListRef &ref);
unique_ptr<LogicalOperator> CreatePlan(BoundCTERef &ref);
BoundStatement BindCopyTo(CopyStatement &stmt);
BoundStatement BindCopyFrom(CopyStatement &stmt);
void BindModifiers(OrderBinder &order_binder, QueryNode &statement, BoundQueryNode &result);
void BindModifierTypes(BoundQueryNode &result, const vector<LogicalType> &sql_types, idx_t projection_index);
BoundStatement BindSummarize(ShowStatement &stmt);
unique_ptr<BoundResultModifier> BindLimit(OrderBinder &order_binder, LimitModifier &limit_mod);
unique_ptr<BoundResultModifier> BindLimitPercent(OrderBinder &order_binder, LimitPercentModifier &limit_mod);
unique_ptr<Expression> BindOrderExpression(OrderBinder &order_binder, unique_ptr<ParsedExpression> expr);
unique_ptr<LogicalOperator> PlanFilter(unique_ptr<Expression> condition, unique_ptr<LogicalOperator> root);
void PlanSubqueries(unique_ptr<Expression> *expr, unique_ptr<LogicalOperator> *root);
unique_ptr<Expression> PlanSubquery(BoundSubqueryExpression &expr, unique_ptr<LogicalOperator> &root);
unique_ptr<LogicalOperator> PlanLateralJoin(unique_ptr<LogicalOperator> left, unique_ptr<LogicalOperator> right,
vector<CorrelatedColumnInfo> &correlated_columns,
JoinType join_type = JoinType::INNER,
unique_ptr<Expression> condition = nullptr);
unique_ptr<LogicalOperator> CastLogicalOperatorToTypes(vector<LogicalType> &source_types,
vector<LogicalType> &target_types,
unique_ptr<LogicalOperator> op);
string FindBinding(const string &using_column, const string &join_side);
bool TryFindBinding(const string &using_column, const string &join_side, string &result);
void AddUsingBindingSet(unique_ptr<UsingColumnSet> set);
string RetrieveUsingBinding(Binder ¤t_binder, UsingColumnSet *current_set, const string &column_name,
const string &join_side, UsingColumnSet *new_set);
void AddCTEMap(CommonTableExpressionMap &cte_map);
void ExpandStarExpressions(vector<unique_ptr<ParsedExpression>> &select_list,
vector<unique_ptr<ParsedExpression>> &new_select_list);
void ExpandStarExpression(unique_ptr<ParsedExpression> expr, vector<unique_ptr<ParsedExpression>> &new_select_list);
bool FindStarExpression(ParsedExpression &expr, StarExpression **star);
void ReplaceStarExpression(unique_ptr<ParsedExpression> &expr, unique_ptr<ParsedExpression> &replacement);
void BindSchemaOrCatalog(string &catalog_name, string &schema_name);
SchemaCatalogEntry *BindCreateSchema(CreateInfo &info);
public:
Binder(bool i_know_what_i_am_doing, ClientContext &context, shared_ptr<Binder> parent, bool inherit_ctes);
};
}
namespace duckdb {
struct OperatorExtensionInfo {
DUCKDB_API virtual ~OperatorExtensionInfo() {
}
};
typedef BoundStatement (*bind_function_t)(ClientContext &context, Binder &binder, OperatorExtensionInfo *info,
SQLStatement &statement);
struct LogicalExtensionOperator;
class OperatorExtension {
public:
bind_function_t Bind;
shared_ptr<OperatorExtensionInfo> operator_info;
virtual std::string GetName() = 0;
virtual std::unique_ptr<LogicalExtensionOperator> Deserialize(LogicalDeserializationState &state,
FieldReader &reader) = 0;
DUCKDB_API virtual ~OperatorExtension() {
}
};
}
namespace duckdb {
class CastFunctionSet;
class ClientContext;
class ErrorManager;
class CompressionFunction;
class TableFunctionRef;
class OperatorExtension;
class StorageExtension;
struct CompressionFunctionSet;
struct DBConfig;
enum class CheckpointAbort : uint8_t {
NO_ABORT = 0,
DEBUG_ABORT_BEFORE_TRUNCATE = 1,
DEBUG_ABORT_BEFORE_HEADER = 2,
DEBUG_ABORT_AFTER_FREE_LIST_WRITE = 3
};
typedef void (*set_global_function_t)(DatabaseInstance *db, DBConfig &config, const Value ¶meter);
typedef void (*set_local_function_t)(ClientContext &context, const Value ¶meter);
typedef void (*reset_global_function_t)(DatabaseInstance *db, DBConfig &config);
typedef void (*reset_local_function_t)(ClientContext &context);
typedef Value (*get_setting_function_t)(ClientContext &context);
struct ConfigurationOption {
const char *name;
const char *description;
LogicalTypeId parameter_type;
set_global_function_t set_global;
set_local_function_t set_local;
reset_global_function_t reset_global;
reset_local_function_t reset_local;
get_setting_function_t get_setting;
};
typedef void (*set_option_callback_t)(ClientContext &context, SetScope scope, Value ¶meter);
struct ExtensionOption {
ExtensionOption(string description_p, LogicalType type_p, set_option_callback_t set_function_p,
Value default_value_p)
: description(std::move(description_p)), type(std::move(type_p)), set_function(set_function_p),
default_value(std::move(default_value_p)) {
}
string description;
LogicalType type;
set_option_callback_t set_function;
Value default_value;
};
struct DBConfigOptions {
string database_path;
AccessMode access_mode = AccessMode::AUTOMATIC;
idx_t checkpoint_wal_size = 1 << 24;
bool use_direct_io = false;
bool load_extensions = true;
idx_t maximum_memory = (idx_t)-1;
idx_t maximum_threads = (idx_t)-1;
idx_t external_threads = 0;
bool use_temporary_directory = true;
string temporary_directory;
string collation = string();
OrderType default_order_type = OrderType::ASCENDING;
OrderByNullType default_null_order = OrderByNullType::NULLS_FIRST;
bool enable_external_access = true;
bool object_cache_enable = false;
bool http_metadata_cache_enable = false;
bool force_checkpoint = false;
bool checkpoint_on_shutdown = true;
CheckpointAbort checkpoint_abort = CheckpointAbort::NO_ABORT;
bool initialize_default_database = true;
set<OptimizerType> disabled_optimizers;
CompressionType force_compression = CompressionType::COMPRESSION_AUTO;
BitpackingMode force_bitpacking_mode = BitpackingMode::AUTO;
WindowAggregationMode window_mode = WindowAggregationMode::WINDOW;
bool preserve_insertion_order = true;
case_insensitive_map_t<Value> set_variables;
case_insensitive_map_t<Value> set_variable_defaults;
string extension_directory;
bool allow_unsigned_extensions = false;
bool enable_fsst_vectors = false;
bool experimental_parallel_csv_reader = false;
bool immediate_transaction_mode = false;
unordered_map<string, Value> unrecognized_options;
bool operator==(const DBConfigOptions &other) const;
};
struct DBConfig {
friend class DatabaseInstance;
friend class StorageManager;
public:
DUCKDB_API DBConfig();
DUCKDB_API DBConfig(std::unordered_map<string, string> &config_dict, bool read_only);
DUCKDB_API ~DBConfig();
mutex config_lock;
vector<ReplacementScan> replacement_scans;
case_insensitive_map_t<ExtensionOption> extension_parameters;
unique_ptr<FileSystem> file_system;
unique_ptr<Allocator> allocator;
DBConfigOptions options;
vector<ParserExtension> parser_extensions;
vector<OptimizerExtension> optimizer_extensions;
unique_ptr<ErrorManager> error_manager;
shared_ptr<Allocator> default_allocator;
vector<std::unique_ptr<OperatorExtension>> operator_extensions;
case_insensitive_map_t<std::unique_ptr<StorageExtension>> storage_extensions;
public:
DUCKDB_API static DBConfig &GetConfig(ClientContext &context);
DUCKDB_API static DBConfig &GetConfig(DatabaseInstance &db);
DUCKDB_API static DBConfig &Get(AttachedDatabase &db);
DUCKDB_API static const DBConfig &GetConfig(const ClientContext &context);
DUCKDB_API static const DBConfig &GetConfig(const DatabaseInstance &db);
DUCKDB_API static vector<ConfigurationOption> GetOptions();
DUCKDB_API static idx_t GetOptionCount();
DUCKDB_API static vector<string> GetOptionNames();
DUCKDB_API void AddExtensionOption(const string &name, string description, LogicalType parameter,
const Value &default_value = Value(), set_option_callback_t function = nullptr);
DUCKDB_API static ConfigurationOption *GetOptionByIndex(idx_t index);
DUCKDB_API static ConfigurationOption *GetOptionByName(const string &name);
DUCKDB_API void SetOption(const ConfigurationOption &option, const Value &value);
DUCKDB_API void SetOption(DatabaseInstance *db, const ConfigurationOption &option, const Value &value);
DUCKDB_API void SetOptionByName(const string &name, const Value &value);
DUCKDB_API void ResetOption(DatabaseInstance *db, const ConfigurationOption &option);
DUCKDB_API void SetOption(const string &name, Value value);
DUCKDB_API void ResetOption(const string &name);
DUCKDB_API static idx_t ParseMemoryLimit(const string &arg);
DUCKDB_API vector<CompressionFunction *> GetCompressionFunctions(PhysicalType data_type);
DUCKDB_API CompressionFunction *GetCompressionFunction(CompressionType type, PhysicalType data_type);
bool operator==(const DBConfig &other);
bool operator!=(const DBConfig &other);
DUCKDB_API CastFunctionSet &GetCastFunctions();
void SetDefaultMaxThreads();
void SetDefaultMaxMemory();
private:
unique_ptr<CompressionFunctionSet> compression_functions;
unique_ptr<CastFunctionSet> cast_functions;
};
}
namespace duckdb {
class DatabaseInstance;
class MetaTransaction;
class ValidChecker {
public:
ValidChecker();
DUCKDB_API static ValidChecker &Get(DatabaseInstance &db);
DUCKDB_API static ValidChecker &Get(MetaTransaction &transaction);
DUCKDB_API void Invalidate(string error);
DUCKDB_API bool IsInvalidated();
DUCKDB_API string InvalidatedMessage();
template <class T>
static bool IsInvalidated(T &o) {
return Get(o).IsInvalidated();
}
template <class T>
static void Invalidate(T &o, string error) {
Get(o).Invalidate(std::move(error));
}
template <class T>
static string InvalidatedMessage(T &o) {
return Get(o).InvalidatedMessage();
}
private:
mutex invalidate_lock;
atomic<bool> is_invalidated;
string invalidated_msg;
};
}
namespace duckdb {
class DuckDB;
class Extension {
public:
DUCKDB_API virtual ~Extension();
DUCKDB_API virtual void Load(DuckDB &db) = 0;
DUCKDB_API virtual std::string Name() = 0;
};
}
namespace duckdb {
class BufferManager;
class DatabaseManager;
class StorageManager;
class Catalog;
class TransactionManager;
class ConnectionManager;
class FileSystem;
class TaskScheduler;
class ObjectCache;
struct AttachInfo;
class DatabaseInstance : public std::enable_shared_from_this<DatabaseInstance> {
friend class DuckDB;
public:
DUCKDB_API DatabaseInstance();
DUCKDB_API ~DatabaseInstance();
DBConfig config;
public:
DUCKDB_API BufferManager &GetBufferManager();
DUCKDB_API DatabaseManager &GetDatabaseManager();
DUCKDB_API FileSystem &GetFileSystem();
DUCKDB_API TaskScheduler &GetScheduler();
DUCKDB_API ObjectCache &GetObjectCache();
DUCKDB_API ConnectionManager &GetConnectionManager();
DUCKDB_API ValidChecker &GetValidChecker();
DUCKDB_API void SetExtensionLoaded(const std::string &extension_name);
idx_t NumberOfThreads();
DUCKDB_API static DatabaseInstance &GetDatabase(ClientContext &context);
DUCKDB_API const unordered_set<std::string> &LoadedExtensions();
DUCKDB_API bool ExtensionIsLoaded(const std::string &name);
DUCKDB_API bool TryGetCurrentSetting(const std::string &key, Value &result);
string ExtractDatabaseType(string &path);
unique_ptr<AttachedDatabase> CreateAttachedDatabase(AttachInfo &info, const string &type, AccessMode access_mode);
private:
void Initialize(const char *path, DBConfig *config);
void Configure(DBConfig &config);
private:
unique_ptr<BufferManager> buffer_manager;
unique_ptr<DatabaseManager> db_manager;
unique_ptr<TaskScheduler> scheduler;
unique_ptr<ObjectCache> object_cache;
unique_ptr<ConnectionManager> connection_manager;
unordered_set<std::string> loaded_extensions;
ValidChecker db_validity;
};
class DuckDB {
public:
DUCKDB_API explicit DuckDB(const char *path = nullptr, DBConfig *config = nullptr);
DUCKDB_API explicit DuckDB(const string &path, DBConfig *config = nullptr);
DUCKDB_API explicit DuckDB(DatabaseInstance &instance);
DUCKDB_API ~DuckDB();
shared_ptr<DatabaseInstance> instance;
public:
template <class T>
void LoadExtension() {
T extension;
if (ExtensionIsLoaded(extension.Name())) {
return;
}
extension.Load(*this);
instance->SetExtensionLoaded(extension.Name());
}
DUCKDB_API FileSystem &GetFileSystem();
DUCKDB_API idx_t NumberOfThreads();
DUCKDB_API static const char *SourceID();
DUCKDB_API static const char *LibraryVersion();
DUCKDB_API static idx_t StandardVectorSize();
DUCKDB_API static string Platform();
DUCKDB_API bool ExtensionIsLoaded(const std::string &name);
};
}
#if defined(DUCKDB_BUILD_LOADABLE_EXTENSION) && defined(DUCKDB_EXTENSION_MAIN)
#if defined(_WIN32) || defined(_WIN64)
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
#endif
#include <windows.h>
#undef CreateDirectory
#undef MoveFile
#undef RemoveDirectory
#include <delayimp.h>
extern "C" {
FARPROC WINAPI duckdb_dllimport_delay_hook(unsigned dliNotify, PDelayLoadInfo pdli) {
switch (dliNotify) {
case dliNotePreLoadLibrary:
if (strcmp(pdli->szDll, "duckdb.dll") != 0) {
return NULL;
}
return (FARPROC)GetModuleHandle(NULL);
default:
return NULL;
}
return NULL;
}
ExternC const PfnDliHook __pfnDliNotifyHook2 = duckdb_dllimport_delay_hook;
ExternC const PfnDliHook __pfnDliFailureHook2 = duckdb_dllimport_delay_hook;
}
#endif
#endif
namespace duckdb {
class ColumnDataCollection;
class ClientContext;
class DuckDB;
class TableCatalogEntry;
class Connection;
enum class AppenderType : uint8_t {
LOGICAL, PHYSICAL };
class BaseAppender {
protected:
static constexpr const idx_t FLUSH_COUNT = STANDARD_VECTOR_SIZE * 100;
Allocator &allocator;
vector<LogicalType> types;
unique_ptr<ColumnDataCollection> collection;
DataChunk chunk;
idx_t column = 0;
AppenderType appender_type;
protected:
DUCKDB_API BaseAppender(Allocator &allocator, AppenderType type);
DUCKDB_API BaseAppender(Allocator &allocator, vector<LogicalType> types, AppenderType type);
public:
DUCKDB_API virtual ~BaseAppender();
DUCKDB_API void BeginRow();
DUCKDB_API void EndRow();
template <class T>
void Append(T value) {
throw Exception("Undefined type for Appender::Append!");
}
DUCKDB_API void Append(const char *value, uint32_t length);
template <typename... Args>
void AppendRow(Args... args) {
BeginRow();
AppendRowRecursive(args...);
}
DUCKDB_API void Flush();
DUCKDB_API void Close();
DUCKDB_API vector<LogicalType> &GetTypes() {
return types;
}
DUCKDB_API idx_t CurrentColumn() {
return column;
}
DUCKDB_API void AppendDataChunk(DataChunk &value);
protected:
void Destructor();
virtual void FlushInternal(ColumnDataCollection &collection) = 0;
void InitializeChunk();
void FlushChunk();
template <class T>
void AppendValueInternal(T value);
template <class SRC, class DST>
void AppendValueInternal(Vector &vector, SRC input);
template <class SRC, class DST>
void AppendDecimalValueInternal(Vector &vector, SRC input);
void AppendRowRecursive() {
EndRow();
}
template <typename T, typename... Args>
void AppendRowRecursive(T value, Args... args) {
Append<T>(value);
AppendRowRecursive(args...);
}
void AppendValue(const Value &value);
};
class Appender : public BaseAppender {
shared_ptr<ClientContext> context;
unique_ptr<TableDescription> description;
public:
DUCKDB_API Appender(Connection &con, const string &schema_name, const string &table_name);
DUCKDB_API Appender(Connection &con, const string &table_name);
DUCKDB_API ~Appender() override;
protected:
void FlushInternal(ColumnDataCollection &collection) override;
};
class InternalAppender : public BaseAppender {
ClientContext &context;
TableCatalogEntry &table;
public:
DUCKDB_API InternalAppender(ClientContext &context, TableCatalogEntry &table);
DUCKDB_API ~InternalAppender() override;
protected:
void FlushInternal(ColumnDataCollection &collection) override;
};
template <>
DUCKDB_API void BaseAppender::Append(bool value);
template <>
DUCKDB_API void BaseAppender::Append(int8_t value);
template <>
DUCKDB_API void BaseAppender::Append(int16_t value);
template <>
DUCKDB_API void BaseAppender::Append(int32_t value);
template <>
DUCKDB_API void BaseAppender::Append(int64_t value);
template <>
DUCKDB_API void BaseAppender::Append(hugeint_t value);
template <>
DUCKDB_API void BaseAppender::Append(uint8_t value);
template <>
DUCKDB_API void BaseAppender::Append(uint16_t value);
template <>
DUCKDB_API void BaseAppender::Append(uint32_t value);
template <>
DUCKDB_API void BaseAppender::Append(uint64_t value);
template <>
DUCKDB_API void BaseAppender::Append(float value);
template <>
DUCKDB_API void BaseAppender::Append(double value);
template <>
DUCKDB_API void BaseAppender::Append(date_t value);
template <>
DUCKDB_API void BaseAppender::Append(dtime_t value);
template <>
DUCKDB_API void BaseAppender::Append(timestamp_t value);
template <>
DUCKDB_API void BaseAppender::Append(interval_t value);
template <>
DUCKDB_API void BaseAppender::Append(const char *value);
template <>
DUCKDB_API void BaseAppender::Append(string_t value);
template <>
DUCKDB_API void BaseAppender::Append(Value value);
template <>
DUCKDB_API void BaseAppender::Append(std::nullptr_t value);
}
struct ArrowSchema;
namespace duckdb {
struct ArrowConverter {
DUCKDB_API static void ToArrowSchema(ArrowSchema *out_schema, vector<LogicalType> &types, vector<string> &names,
string &config_timezone);
DUCKDB_API static void ToArrowArray(DataChunk &input, ArrowArray *out_array);
};
}
namespace duckdb {
class Blob {
public:
static constexpr const char *HEX_TABLE = "0123456789ABCDEF";
static const int HEX_MAP[256];
static constexpr const char *BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static constexpr const char BASE64_PADDING = '=';
public:
DUCKDB_API static idx_t GetStringSize(string_t blob);
DUCKDB_API static void ToString(string_t blob, char *output);
DUCKDB_API static string ToString(string_t blob);
DUCKDB_API static bool TryGetBlobSize(string_t str, idx_t &result_size, string *error_message);
DUCKDB_API static idx_t GetBlobSize(string_t str);
DUCKDB_API static void ToBlob(string_t str, data_ptr_t output);
DUCKDB_API static string ToBlob(string_t str);
DUCKDB_API static idx_t ToBase64Size(string_t blob);
DUCKDB_API static void ToBase64(string_t blob, char *output);
DUCKDB_API static idx_t FromBase64Size(string_t str);
DUCKDB_API static void FromBase64(string_t str, data_ptr_t output, idx_t output_size);
};
}
namespace duckdb {
template <class PHYSICAL_TYPE>
struct DecimalWidth {};
template <>
struct DecimalWidth<int16_t> {
static constexpr uint8_t max = 4;
};
template <>
struct DecimalWidth<int32_t> {
static constexpr uint8_t max = 9;
};
template <>
struct DecimalWidth<int64_t> {
static constexpr uint8_t max = 18;
};
template <>
struct DecimalWidth<hugeint_t> {
static constexpr uint8_t max = 38;
};
class Decimal {
public:
static constexpr uint8_t MAX_WIDTH_INT16 = DecimalWidth<int16_t>::max;
static constexpr uint8_t MAX_WIDTH_INT32 = DecimalWidth<int32_t>::max;
static constexpr uint8_t MAX_WIDTH_INT64 = DecimalWidth<int64_t>::max;
static constexpr uint8_t MAX_WIDTH_INT128 = DecimalWidth<hugeint_t>::max;
static constexpr uint8_t MAX_WIDTH_DECIMAL = MAX_WIDTH_INT128;
public:
static string ToString(int16_t value, uint8_t width, uint8_t scale);
static string ToString(int32_t value, uint8_t width, uint8_t scale);
static string ToString(int64_t value, uint8_t width, uint8_t scale);
static string ToString(hugeint_t value, uint8_t width, uint8_t scale);
};
}
namespace duckdb {
class ClientContext;
struct RandomEngine;
class UUID {
public:
constexpr static const uint8_t STRING_SIZE = 36;
static bool FromString(string str, hugeint_t &result);
static bool FromCString(const char *str, idx_t len, hugeint_t &result) {
return FromString(string(str, 0, len), result);
}
static void ToString(hugeint_t input, char *buf);
static hugeint_t GenerateRandomUUID(RandomEngine &engine);
static hugeint_t GenerateRandomUUID();
static string ToString(hugeint_t input) {
char buff[STRING_SIZE];
ToString(input, buff);
return string(buff, STRING_SIZE);
}
static hugeint_t FromString(string str) {
hugeint_t result;
FromString(str, result);
return result;
}
};
}
namespace duckdb {
struct dtime_t;
class Time {
public:
DUCKDB_API static dtime_t FromString(const string &str, bool strict = false);
DUCKDB_API static dtime_t FromCString(const char *buf, idx_t len, bool strict = false);
DUCKDB_API static bool TryConvertTime(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict = false);
DUCKDB_API static string ToString(dtime_t time);
DUCKDB_API static string ToUTCOffset(int hour_offset, int minute_offset);
DUCKDB_API static dtime_t FromTime(int32_t hour, int32_t minute, int32_t second, int32_t microseconds = 0);
DUCKDB_API static void Convert(dtime_t time, int32_t &out_hour, int32_t &out_min, int32_t &out_sec,
int32_t &out_micros);
DUCKDB_API static string ConversionError(const string &str);
DUCKDB_API static string ConversionError(string_t str);
private:
static bool TryConvertInternal(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict);
};
}
namespace duckdb {
struct CreateFunctionInfo : public CreateInfo {
explicit CreateFunctionInfo(CatalogType type, string schema = DEFAULT_SCHEMA) : CreateInfo(type, schema) {
D_ASSERT(type == CatalogType::SCALAR_FUNCTION_ENTRY || type == CatalogType::AGGREGATE_FUNCTION_ENTRY ||
type == CatalogType::TABLE_FUNCTION_ENTRY || type == CatalogType::PRAGMA_FUNCTION_ENTRY ||
type == CatalogType::MACRO_ENTRY || type == CatalogType::TABLE_MACRO_ENTRY);
}
string name;
protected:
void SerializeInternal(Serializer &serializer) const override {
serializer.WriteString(name);
}
};
}
namespace duckdb {
enum class PragmaType : uint8_t { PRAGMA_STATEMENT, PRAGMA_CALL };
struct PragmaInfo : public ParseInfo {
string name;
vector<Value> parameters;
named_parameter_map_t named_parameters;
public:
unique_ptr<PragmaInfo> Copy() const {
auto result = make_unique<PragmaInfo>();
result->name = name;
result->parameters = parameters;
result->named_parameters = named_parameters;
return result;
}
};
}
namespace duckdb {
class ClientContext;
typedef string (*pragma_query_t)(ClientContext &context, const FunctionParameters ¶meters);
typedef void (*pragma_function_t)(ClientContext &context, const FunctionParameters ¶meters);
class PragmaFunction : public SimpleNamedParameterFunction {
public:
DUCKDB_API static PragmaFunction PragmaCall(const string &name, pragma_query_t query, vector<LogicalType> arguments,
LogicalType varargs = LogicalType::INVALID);
DUCKDB_API static PragmaFunction PragmaCall(const string &name, pragma_function_t function,
vector<LogicalType> arguments,
LogicalType varargs = LogicalType::INVALID);
DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_query_t query);
DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_function_t function);
DUCKDB_API string ToString() override;
public:
PragmaType type;
pragma_query_t query;
pragma_function_t function;
named_parameter_type_map_t named_parameters;
private:
PragmaFunction(string name, PragmaType pragma_type, pragma_query_t query, pragma_function_t function,
vector<LogicalType> arguments, LogicalType varargs);
};
}
namespace duckdb {
template <class T>
class FunctionSet {
public:
explicit FunctionSet(string name) : name(name) {
}
string name;
vector<T> functions;
public:
void AddFunction(T function) {
functions.push_back(std::move(function));
}
idx_t Size() {
return functions.size();
}
T GetFunctionByOffset(idx_t offset) {
D_ASSERT(offset < functions.size());
return functions[offset];
}
T &GetFunctionReferenceByOffset(idx_t offset) {
D_ASSERT(offset < functions.size());
return functions[offset];
}
bool MergeFunctionSet(FunctionSet<T> new_functions) {
D_ASSERT(!new_functions.functions.empty());
bool need_rewrite_entry = false;
for (auto &new_func : new_functions.functions) {
bool can_add = true;
for (auto &func : functions) {
if (new_func.Equal(func)) {
can_add = false;
break;
}
}
if (can_add) {
functions.push_back(new_func);
need_rewrite_entry = true;
}
}
return need_rewrite_entry;
}
};
class ScalarFunctionSet : public FunctionSet<ScalarFunction> {
public:
DUCKDB_API explicit ScalarFunctionSet(string name);
DUCKDB_API ScalarFunction GetFunctionByArguments(ClientContext &context, const vector<LogicalType> &arguments);
};
class AggregateFunctionSet : public FunctionSet<AggregateFunction> {
public:
DUCKDB_API explicit AggregateFunctionSet(string name);
DUCKDB_API AggregateFunction GetFunctionByArguments(ClientContext &context, const vector<LogicalType> &arguments);
};
class TableFunctionSet : public FunctionSet<TableFunction> {
public:
DUCKDB_API explicit TableFunctionSet(string name);
TableFunction GetFunctionByArguments(ClientContext &context, const vector<LogicalType> &arguments);
};
class PragmaFunctionSet : public FunctionSet<PragmaFunction> {
public:
explicit PragmaFunctionSet(string name) : FunctionSet(std::move(name)) {
}
};
}
namespace duckdb {
struct CreateTableFunctionInfo : public CreateFunctionInfo {
DUCKDB_API explicit CreateTableFunctionInfo(TableFunction function);
DUCKDB_API explicit CreateTableFunctionInfo(TableFunctionSet set);
TableFunctionSet functions;
public:
DUCKDB_API unique_ptr<CreateInfo> Copy() const;
};
}
namespace duckdb {
struct CopyInfo : public ParseInfo {
CopyInfo() : catalog(INVALID_CATALOG), schema(DEFAULT_SCHEMA) {
}
string catalog;
string schema;
string table;
vector<string> select_list;
bool is_from;
string format;
string file_path;
case_insensitive_map_t<vector<Value>> options;
public:
unique_ptr<CopyInfo> Copy() const {
auto result = make_unique<CopyInfo>();
result->catalog = catalog;
result->schema = schema;
result->table = table;
result->select_list = select_list;
result->file_path = file_path;
result->is_from = is_from;
result->format = format;
result->options = options;
return result;
}
};
}
namespace duckdb {
class CopyStatement : public SQLStatement {
public:
CopyStatement();
unique_ptr<CopyInfo> info;
unique_ptr<QueryNode> select_statement;
string ToString() const override;
string CopyOptionsToString(const string &format, const case_insensitive_map_t<vector<Value>> &options) const;
protected:
CopyStatement(const CopyStatement &other);
public:
DUCKDB_API unique_ptr<SQLStatement> Copy() const override;
private:
};
}
namespace duckdb {
class Binder;
struct BoundStatement;
class ExecutionContext;
struct LocalFunctionData {
virtual ~LocalFunctionData() {
}
};
struct GlobalFunctionData {
virtual ~GlobalFunctionData() {
}
};
typedef BoundStatement (*copy_to_plan_t)(Binder &binder, CopyStatement &stmt);
typedef unique_ptr<FunctionData> (*copy_to_bind_t)(ClientContext &context, CopyInfo &info, vector<string> &names,
vector<LogicalType> &sql_types);
typedef unique_ptr<LocalFunctionData> (*copy_to_initialize_local_t)(ExecutionContext &context, FunctionData &bind_data);
typedef unique_ptr<GlobalFunctionData> (*copy_to_initialize_global_t)(ClientContext &context, FunctionData &bind_data,
const string &file_path);
typedef void (*copy_to_sink_t)(ExecutionContext &context, FunctionData &bind_data, GlobalFunctionData &gstate,
LocalFunctionData &lstate, DataChunk &input);
typedef void (*copy_to_combine_t)(ExecutionContext &context, FunctionData &bind_data, GlobalFunctionData &gstate,
LocalFunctionData &lstate);
typedef void (*copy_to_finalize_t)(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate);
typedef void (*copy_to_serialize_t)(FieldWriter &writer, const FunctionData &bind_data, const CopyFunction &function);
typedef unique_ptr<FunctionData> (*copy_to_deserialize_t)(ClientContext &context, FieldReader &reader,
CopyFunction &function);
typedef unique_ptr<FunctionData> (*copy_from_bind_t)(ClientContext &context, CopyInfo &info,
vector<string> &expected_names,
vector<LogicalType> &expected_types);
typedef bool (*copy_to_is_parallel_t)(ClientContext &context, FunctionData &bind_data);
class CopyFunction : public Function {
public:
explicit CopyFunction(string name)
: Function(name), plan(nullptr), copy_to_bind(nullptr), copy_to_initialize_local(nullptr),
copy_to_initialize_global(nullptr), copy_to_sink(nullptr), copy_to_combine(nullptr),
copy_to_finalize(nullptr), parallel(nullptr), serialize(nullptr), deserialize(nullptr),
copy_from_bind(nullptr) {
}
copy_to_plan_t plan;
copy_to_bind_t copy_to_bind;
copy_to_initialize_local_t copy_to_initialize_local;
copy_to_initialize_global_t copy_to_initialize_global;
copy_to_sink_t copy_to_sink;
copy_to_combine_t copy_to_combine;
copy_to_finalize_t copy_to_finalize;
copy_to_is_parallel_t parallel;
copy_to_serialize_t serialize;
copy_to_deserialize_t deserialize;
copy_from_bind_t copy_from_bind;
TableFunction copy_from_function;
string extension;
};
}
namespace duckdb {
struct CreateCopyFunctionInfo : public CreateInfo {
DUCKDB_API explicit CreateCopyFunctionInfo(CopyFunction function);
string name;
CopyFunction function;
protected:
void SerializeInternal(Serializer &) const override;
public:
unique_ptr<CreateInfo> Copy() const override;
};
}