Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ unique_ptr<FunctionData> UnpivotBind(BindScalarFunctionInput &input) {
}
child_type = LogicalType::NormalizeType(child_type);

auto &function_args = bound_function.GetArguments();
function_args.clear();
function_args.reserve(arguments.size());
for (idx_t i = 0; i < arguments.size(); i++) {
function_args.push_back(child_type);
}
bound_function.SetReturnType(LogicalType::LIST(child_type));
return make_uniq<VariableReturnBindData>(bound_function.GetReturnType());
}
Expand Down
22 changes: 20 additions & 2 deletions src/duckdb/src/common/hive_partitioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,30 @@ string HivePartitioning::Escape(const string &input) {
return StringUtil::URLEncode(input);
}

string HivePartitioning::EscapeValue(const string &input) {
auto result = Escape(input);
// the comparison is case-insensitive because on a case-insensitive file system a value that differs only in
// case still lands in the directory that is reserved for NULL values
if (!StringUtil::CIEquals(result, DEFAULT_PARTITION_NAME)) {
return result;
}
// percent-encode the first character so the value gets its own directory while still unescaping back to the
// original value
static constexpr const char *HEX_DIGIT = "0123456789ABCDEF";
const auto first = static_cast<unsigned char>(result[0]);
string escaped = "%";
escaped += HEX_DIGIT[first >> 4];
escaped += HEX_DIGIT[first & 15];
escaped += result.substr(1);
return escaped;
}

string HivePartitioning::Unescape(const string &input) {
return StringUtil::URLDecode(input);
}

bool HivePartitioning::IsNull(const string &input) {
return StringUtil::CIEquals(input, "NULL") || input == "__HIVE_DEFAULT_PARTITION__";
return StringUtil::CIEquals(input, "NULL") || input == DEFAULT_PARTITION_NAME;
}

// matches hive partitions in file name. For example:
Expand Down Expand Up @@ -132,7 +150,7 @@ std::map<string, string> HivePartitioning::Parse(const string &filename) {
Value HivePartitioning::GetValue(ClientContext &context, const string &key, const string &str_val,
const LogicalType &type) {
// On SQLNULL, DuckDB writes "__HIVE_DEFAULT_PARTITION__", instead of string version "NULL".
if (str_val == "__HIVE_DEFAULT_PARTITION__") {
if (str_val == DEFAULT_PARTITION_NAME) {
return Value(type);
}
if (type.id() == LogicalTypeId::VARCHAR) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2990,9 +2990,9 @@ PartitionDirectory PartitionFileRequestBuilder::BuildDirectory(string path) cons
p_dir += HivePartitioning::Escape(partition_col_name.GetIdentifierName());
p_dir += "=";
if (partition_value.IsNull()) {
p_dir += "__HIVE_DEFAULT_PARTITION__";
p_dir += HivePartitioning::DEFAULT_PARTITION_NAME;
} else {
p_dir += HivePartitioning::Escape(partition_value.ToString());
p_dir += HivePartitioning::EscapeValue(partition_value.ToString());
}
result.path = fs.JoinPath(result.path, p_dir);
result.directories.push_back(result.path);
Expand Down
44 changes: 44 additions & 0 deletions src/duckdb/src/function/table/system/duckdb_dialects.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "duckdb/function/table/system_functions.hpp"

#include "duckdb/main/client_context.hpp"
#include "duckdb/main/extension_callback_manager.hpp"
#include "duckdb/parser/dialect_extension.hpp"

namespace duckdb {

struct DuckDBDialectsData : public GlobalTableFunctionState {
vector<string> dialects;
idx_t offset = 0;
};

static unique_ptr<FunctionData> DuckDBDialectsBind(ClientContext &context, TableFunctionBindInput &input,
vector<LogicalType> &return_types, vector<Identifier> &names) {
names.emplace_back("dialect_name");
return_types.emplace_back(LogicalType::VARCHAR);
return nullptr;
}

static unique_ptr<GlobalTableFunctionState> DuckDBDialectsInit(ClientContext &context, TableFunctionInitInput &input) {
auto result = make_uniq<DuckDBDialectsData>();
for (auto &dialect : ExtensionCallbackManager::Get(context).DialectExtensions()) {
result->dialects.push_back(dialect.name);
}
return std::move(result);
}

static void DuckDBDialectsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) {
auto &data = data_p.global_state->Cast<DuckDBDialectsData>();
auto &dialect_name = output.data[0];
idx_t count = 0;
while (data.offset < data.dialects.size() && count < STANDARD_VECTOR_SIZE) {
dialect_name.Append(Value(data.dialects[data.offset++]));
count++;
}
}

void DuckDBDialectsFun::RegisterFunction(BuiltinFunctions &set) {
set.AddFunction(
TableFunction("duckdb_dialects", {}, DuckDBDialectsFunction, DuckDBDialectsBind, DuckDBDialectsInit));
}

} // namespace duckdb
1 change: 1 addition & 0 deletions src/duckdb/src/function/table/system_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void BuiltinFunctions::RegisterSQLiteFunctions() {
DuckDBIndexesFun::RegisterFunction(*this);
DuckDBSchemasFun::RegisterFunction(*this);
DuckDBDependenciesFun::RegisterFunction(*this);
DuckDBDialectsFun::RegisterFunction(*this);
DuckDBExtensionsFun::RegisterFunction(*this);
RegisterExternalResourceTypeFun::RegisterFunction(*this);
CreateExternalResourceFun::RegisterFunction(*this);
Expand Down
6 changes: 3 additions & 3 deletions src/duckdb/src/function/table/version/pragma_version.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef DUCKDB_PATCH_VERSION
#define DUCKDB_PATCH_VERSION "0-alpha38143"
#define DUCKDB_PATCH_VERSION "0-alpha38195"
#endif
#ifndef DUCKDB_MINOR_VERSION
#define DUCKDB_MINOR_VERSION 0
Expand All @@ -8,10 +8,10 @@
#define DUCKDB_MAJOR_VERSION 2
#endif
#ifndef DUCKDB_VERSION
#define DUCKDB_VERSION "v2.0.0-alpha38143"
#define DUCKDB_VERSION "v2.0.0-alpha38195"
#endif
#ifndef DUCKDB_SOURCE_ID
#define DUCKDB_SOURCE_ID "11dc00c898"
#define DUCKDB_SOURCE_ID "8cbdaba6ac"
#endif
#include "duckdb/function/table/system_functions.hpp"
#include "duckdb/main/database.hpp"
Expand Down
6 changes: 6 additions & 0 deletions src/duckdb/src/include/duckdb/common/hive_partitioning.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ struct HivePartitioningFilterInfo {
};

class HivePartitioning {
public:
//! The directory name that is written for a NULL partition value
static constexpr const char *DEFAULT_PARTITION_NAME = "__HIVE_DEFAULT_PARTITION__";

public:
//! Parse a filename that follows the hive partitioning scheme
DUCKDB_API static std::map<string, string> Parse(const string &filename);
Expand All @@ -39,6 +43,8 @@ class HivePartitioning {
const LogicalType &type);
//! Escape a hive partition key or value using URL encoding
DUCKDB_API static string Escape(const string &input);
//! Escape a non-NULL hive partition value, avoiding a collision with the NULL partition directory
DUCKDB_API static string EscapeValue(const string &input);
//! Unescape a hive partition key or value encoded using URL encoding
DUCKDB_API static string Unescape(const string &input);
//! Whether the value is a null marker when detecting Hive partition types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,14 @@ class MultiFileFunction : public TableFunction {
auto primary_index = column_index.GetPrimaryIndex();
const auto &col_name = bind_data.names[primary_index];

// a hive partitioning column overrides any file column of the same name - the statistics stored in the
// file describe the overridden column and can even have a different type, so they cannot be used here
for (auto &hive_partitioning_index : bind_data.reader_bind.hive_partitioning_indexes) {
if (hive_partitioning_index.index == primary_index) {
return nullptr;
}
}

// NOTE: we do not want to parse the file metadata for the sole purpose of getting column statistics
if (bind_data.file_list->GetExpandResult() == FileExpandResult::MULTIPLE_FILES) {
if (!bind_data.file_options.union_by_name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ struct DuckDBDependenciesFun {
static void RegisterFunction(BuiltinFunctions &set);
};

struct DuckDBDialectsFun {
static void RegisterFunction(BuiltinFunctions &set);
};

struct DuckDBExtensionsFun {
static void RegisterFunction(BuiltinFunctions &set);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace duckdb {

class ClientContext;
class DatabaseInstance;
class DialectExtension;
class ExtensionCallback;
class OperatorExtension;
class OptimizerExtension;
Expand All @@ -42,6 +43,7 @@ class ExtensionCallbackManager {
static const ExtensionCallbackManager &Get(const ClientContext &context);

void Register(ParserExtension extension);
void Register(DialectExtension extension);
void Register(PlannerExtension extension);
void Register(OptimizerExtension extension);
void Register(shared_ptr<OperatorExtension> extension);
Expand All @@ -52,11 +54,13 @@ class ExtensionCallbackManager {
ExtensionCallbackIteratorHelper<shared_ptr<OperatorExtension>> OperatorExtensions() const;
ExtensionCallbackIteratorHelper<OptimizerExtension> OptimizerExtensions() const;
ExtensionCallbackIteratorHelper<ParserExtension> ParserExtensions() const;
ExtensionCallbackIteratorHelper<DialectExtension> DialectExtensions() const;
ExtensionCallbackIteratorHelper<PlannerExtension> PlannerExtensions() const;
ExtensionCallbackIteratorHelper<shared_ptr<ExtensionCallback>> ExtensionCallbacks() const;
optional_ptr<StorageExtension> FindStorageExtension(const string &name) const;
optional_ptr<ProfilerExtension> FindProfilerExtension(const string &name) const;
bool HasParserExtensions() const;
bool HasDialectExtension(const string &name) const;

private:
mutex registry_lock;
Expand Down
11 changes: 11 additions & 0 deletions src/duckdb/src/include/duckdb/main/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,17 @@ struct ConfigureProfilingSetting {
static Value GetSetting(const ClientContext &context);
};

struct CurrentDialectSetting {
using RETURN_TYPE = string;
static constexpr const char *Name = "current_dialect";
static constexpr const char *Description = "The SQL dialect used by the parser";
static constexpr const char *InputType = "VARCHAR";
static constexpr const char *DefaultValue = "duckdb";
static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY;
static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX();
static void OnSet(SettingCallbackInfo &info, Value &input);
};

struct CurrentTransactionInvalidationPolicySetting {
using RETURN_TYPE = string;
static constexpr const char *Name = "current_transaction_invalidation_policy";
Expand Down
27 changes: 27 additions & 0 deletions src/duckdb/src/include/duckdb/parser/dialect_extension.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===----------------------------------------------------------------------===//
// DuckDB
//
// duckdb/parser/dialect_extension.hpp
//
//
//===----------------------------------------------------------------------===//

#pragma once

#include "duckdb/common/common.hpp"

namespace duckdb {
struct DBConfig;

//! A named SQL dialect that can customize the PEG parser.
class DialectExtension {
public:
explicit DialectExtension(string name_p) : name(std::move(name_p)) {
}

string name;

static void Register(DBConfig &config, DialectExtension extension);
};

} // namespace duckdb
13 changes: 13 additions & 0 deletions src/duckdb/src/include/duckdb/parser/peg/matcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ class Matcher {
bool packrat_memoized = false;
};

class KeywordInfo {
public:
KeywordInfo() {
}
explicit KeywordInfo(int32_t score_bonus, char extra_char = ' ')
: score_bonus(score_bonus), extra_char(extra_char) {
}

public:
int32_t score_bonus = 0;
char extra_char = '\0';
};

class MatcherAllocator {
public:
Matcher &Allocate(unique_ptr<Matcher> matcher);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class OptimisticDataWriter {
//! Rollback
void Rollback();

//! Whether this writer can write to disk at all (not temporary / in-memory / read-only)
bool CanWriteToDisk() const;

//! Return the client context.
ClientContext &GetClientContext() {
return context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class DuckTransaction : public Transaction {
void SetModifications(DatabaseModificationType type) override;

bool ShouldWriteToWAL(AttachedDatabase &db);
ErrorData PreFlushOptimisticBlocks(AttachedDatabase &db) noexcept;
ErrorData WriteToWAL(ClientContext &context, AttachedDatabase &db,
unique_ptr<StorageCommitState> &commit_state) noexcept;
//! Commit the current transaction with the given commit identifier. Returns an error message if the transaction
Expand Down
15 changes: 15 additions & 0 deletions src/duckdb/src/include/duckdb/transaction/local_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ class LocalTableStorage : public enable_shared_from_this<LocalTableStorage> {
//! Write a new row group to disk (if possible)
void WriteNewRowGroup(idx_t flushed_row_group_idx);
void FlushBlocks();
//! Whether Flush() takes the bulk-append path for this storage: the append covers at least one
//! full row group and there are no deletes. Only depends on transaction-local state, i.e. this
//! can be decided before taking any locks.
bool IsBulkAppend() const;
//! Whether the optimistic writer of this storage writes to disk (not temporary / in-memory / read-only)
bool WritesToDisk() const;
//! Whether this storage holds optimistically written (flushed) row groups
bool HasFlushedRowGroups() const;
void Rollback();
idx_t EstimatedSize();

Expand Down Expand Up @@ -115,6 +123,7 @@ class LocalTableManager {
public:
shared_ptr<LocalTableStorage> MoveEntry(DataTable &table);
reference_map_t<DataTable, shared_ptr<LocalTableStorage>> MoveEntries();
vector<shared_ptr<LocalTableStorage>> GetEntries() const;
optional_ptr<LocalTableStorage> GetStorage(DataTable &table) const;
LocalTableStorage &GetOrCreateStorage(ClientContext &context, DataTable &table);
idx_t EstimatedSize() const;
Expand Down Expand Up @@ -213,10 +222,16 @@ class LocalStorage {
return context;
}

void FlushBulkAppendBlocksAndSync(AttachedDatabase &db);
bool SyncedFlushedBlocks() const {
return synced_flushed_blocks;
}

private:
ClientContext &context;
DuckTransaction &transaction;
LocalTableManager table_manager;
bool synced_flushed_blocks = false;

private:
void Flush(DataTable &table, LocalTableStorage &storage, optional_ptr<StorageCommitState> commit_state);
Expand Down
11 changes: 6 additions & 5 deletions src/duckdb/src/main/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ static const ConfigurationOption internal_options[] = {
DUCKDB_SETTING_CALLBACK(CheckpointOnDetachSetting),
DUCKDB_GLOBAL(CheckpointThresholdSetting),
DUCKDB_LOCAL(ConfigureProfilingSetting),
DUCKDB_SETTING_CALLBACK(CurrentDialectSetting),
DUCKDB_SETTING_CALLBACK(CurrentTransactionInvalidationPolicySetting),
DUCKDB_SETTING(CustomExtensionRepositorySetting),
DUCKDB_GLOBAL(CustomUserAgentSetting),
Expand Down Expand Up @@ -250,12 +251,12 @@ static const ConfigurationOption internal_options[] = {

static const ConfigurationAlias setting_aliases[] = {DUCKDB_SETTING_ALIAS("configure_metrics", 30),
DUCKDB_SETTING_ALIAS("custom_profiling_settings", 30),
DUCKDB_SETTING_ALIAS("memory_limit", 129),
DUCKDB_SETTING_ALIAS("null_order", 61),
DUCKDB_SETTING_ALIAS("profile_output", 152),
DUCKDB_SETTING_ALIAS("user", 171),
DUCKDB_SETTING_ALIAS("memory_limit", 130),
DUCKDB_SETTING_ALIAS("null_order", 62),
DUCKDB_SETTING_ALIAS("profile_output", 153),
DUCKDB_SETTING_ALIAS("user", 172),
DUCKDB_SETTING_ALIAS("wal_autocheckpoint", 29),
DUCKDB_SETTING_ALIAS("worker_threads", 169),
DUCKDB_SETTING_ALIAS("worker_threads", 170),
FINAL_ALIAS};

vector<ConfigurationOption> DBConfig::GetOptions() {
Expand Down
3 changes: 3 additions & 0 deletions src/duckdb/src/main/database_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ shared_ptr<AttachedDatabase> DatabaseManager::DetachInternal(const Identifier &n
}
attached_db = std::move(entry->second);
databases.erase(entry);
if (name == default_database) {
default_database = databases.empty() ? Identifier() : databases.begin()->first;
}
}
if (attached_db && attached_db->GetCatalog().Supports(RemoteCapability::IS_REMOTE)) {
--remote_catalog_count;
Expand Down
Loading
Loading