From a6482dffaaac017d995664cd827033b1d06c31af Mon Sep 17 00:00:00 2001 From: DuckDB Labs GitHub Bot Date: Sat, 21 Mar 2026 07:07:18 +0000 Subject: [PATCH] Update vendored DuckDB sources to 222ea44eb4 --- .../common/arrow/physical_arrow_collector.cpp | 10 +- src/duckdb/src/common/enum_util.cpp | 18 ++ src/duckdb/src/common/file_system.cpp | 2 +- .../helper/physical_result_collector.cpp | 15 +- .../operator/helper/physical_transaction.cpp | 2 + .../src/function/scalar/list/list_resize.cpp | 4 +- .../function/table/version/pragma_version.cpp | 6 +- .../common/arrow/physical_arrow_collector.hpp | 2 +- .../src/include/duckdb/common/enum_util.hpp | 8 + .../enums/current_transaction_state.hpp | 15 ++ .../src/include/duckdb/execution/executor.hpp | 2 + .../helper/physical_result_collector.hpp | 2 +- .../src/include/duckdb/main/client_config.hpp | 3 +- .../include/duckdb/main/client_context.hpp | 4 +- .../src/include/duckdb/main/settings.hpp | 172 +++++++++-------- .../parser/parsed_data/transaction_info.hpp | 11 +- .../include/duckdb/planner/pragma_handler.hpp | 38 ---- .../duckdb/planner/statement_preprocessor.hpp | 39 ++++ .../transaction/transaction_context.hpp | 16 ++ src/duckdb/src/main/client_context.cpp | 55 ++++-- src/duckdb/src/main/config.cpp | 11 +- .../src/main/extension/extension_helper.cpp | 2 + .../src/main/settings/custom_settings.cpp | 8 + src/duckdb/src/parallel/executor.cpp | 6 + .../parser/parsed_data/transaction_info.cpp | 8 +- src/duckdb/src/planner/pragma_handler.cpp | 84 -------- .../src/planner/statement_preprocessor.cpp | 182 ++++++++++++++++++ .../serialization/serialize_parse_info.cpp | 4 + src/duckdb/ub_src_planner.cpp | 2 +- 29 files changed, 485 insertions(+), 246 deletions(-) create mode 100644 src/duckdb/src/include/duckdb/common/enums/current_transaction_state.hpp delete mode 100644 src/duckdb/src/include/duckdb/planner/pragma_handler.hpp create mode 100644 src/duckdb/src/include/duckdb/planner/statement_preprocessor.hpp delete mode 100644 src/duckdb/src/planner/pragma_handler.cpp create mode 100644 src/duckdb/src/planner/statement_preprocessor.cpp diff --git a/src/duckdb/src/common/arrow/physical_arrow_collector.cpp b/src/duckdb/src/common/arrow/physical_arrow_collector.cpp index a8b225f75..7934a0438 100644 --- a/src/duckdb/src/common/arrow/physical_arrow_collector.cpp +++ b/src/duckdb/src/common/arrow/physical_arrow_collector.cpp @@ -8,23 +8,23 @@ namespace duckdb { -PhysicalOperator &PhysicalArrowCollector::Create(ClientContext &context, PreparedStatementData &data, - idx_t batch_size) { +unique_ptr PhysicalArrowCollector::Create(ClientContext &context, PreparedStatementData &data, + idx_t batch_size) { auto &physical_plan = *data.physical_plan; auto &root = physical_plan.Root(); if (!PhysicalPlanGenerator::PreserveInsertionOrder(context, root)) { // Not an order-preserving plan: use the parallel materialized collector. - return physical_plan.Make(data, true, batch_size); + return make_uniq(physical_plan, data, true, batch_size); } if (!PhysicalPlanGenerator::UseBatchIndex(context, root)) { // Order-preserving plan, and we cannot use the batch index: use single-threaded result collector. - return physical_plan.Make(data, false, batch_size); + return make_uniq(physical_plan, data, false, batch_size); } // Order-preserving plan, and we can use the batch index: use a batch collector. - return physical_plan.Make(data, batch_size); + return make_uniq(physical_plan, data, batch_size); } SinkResultType PhysicalArrowCollector::Sink(ExecutionContext &context, DataChunk &chunk, diff --git a/src/duckdb/src/common/enum_util.cpp b/src/duckdb/src/common/enum_util.cpp index 9897e4d30..4d260816c 100644 --- a/src/duckdb/src/common/enum_util.cpp +++ b/src/duckdb/src/common/enum_util.cpp @@ -5138,6 +5138,24 @@ TimestampCastResult EnumUtil::FromString(const char *value) return static_cast(StringUtil::StringToEnum(GetTimestampCastResultValues(), 5, "TimestampCastResult", value)); } +const StringUtil::EnumStringLiteral *GetTransactionInvalidationPolicyValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(TransactionInvalidationPolicy::STANDARD_POLICY), "STANDARD_POLICY" }, + { static_cast(TransactionInvalidationPolicy::ALL_ERRORS_INVALIDATE_TRANSACTION), "ALL_ERRORS_INVALIDATE_TRANSACTION" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(TransactionInvalidationPolicy value) { + return StringUtil::EnumToString(GetTransactionInvalidationPolicyValues(), 2, "TransactionInvalidationPolicy", static_cast(value)); +} + +template<> +TransactionInvalidationPolicy EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetTransactionInvalidationPolicyValues(), 2, "TransactionInvalidationPolicy", value)); +} + const StringUtil::EnumStringLiteral *GetTransactionModifierTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(TransactionModifierType::TRANSACTION_DEFAULT_MODIFIER), "TRANSACTION_DEFAULT_MODIFIER" }, diff --git a/src/duckdb/src/common/file_system.cpp b/src/duckdb/src/common/file_system.cpp index 514d361c9..8b83c25c6 100644 --- a/src/duckdb/src/common/file_system.cpp +++ b/src/duckdb/src/common/file_system.cpp @@ -770,7 +770,7 @@ int64_t FileHandle::Write(void *buffer, idx_t nr_bytes) { int64_t FileHandle::Write(QueryContext context, void *buffer, idx_t nr_bytes) { if (context.GetClientContext() != nullptr) { - context.GetClientContext()->client_data->profiler->AddToCounter(MetricType::TOTAL_BYTES_READ, nr_bytes); + context.GetClientContext()->client_data->profiler->AddToCounter(MetricType::TOTAL_BYTES_WRITTEN, nr_bytes); } return file_system.Write(*this, buffer, UnsafeNumericCast(nr_bytes)); diff --git a/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp b/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp index df95ce707..ccec5cd19 100644 --- a/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp @@ -22,31 +22,32 @@ PhysicalResultCollector::PhysicalResultCollector(PhysicalPlan &physical_plan, Pr types = data.types; } -PhysicalOperator &PhysicalResultCollector::GetResultCollector(ClientContext &context, PreparedStatementData &data) { +unique_ptr PhysicalResultCollector::GetResultCollector(ClientContext &context, + PreparedStatementData &data) { auto &physical_plan = *data.physical_plan; auto &root = physical_plan.Root(); if (!PhysicalPlanGenerator::PreserveInsertionOrder(context, root)) { // Not an order-preserving plan: use the parallel materialized collector. if (data.output_type == QueryResultOutputType::ALLOW_STREAMING) { - return physical_plan.Make(data, true); + return make_uniq(physical_plan, data, true); } - return physical_plan.Make(data, true); + return make_uniq(physical_plan, data, true); } if (!PhysicalPlanGenerator::UseBatchIndex(context, root)) { // Order-preserving plan, and we cannot use the batch index: use single-threaded result collector. if (data.output_type == QueryResultOutputType::ALLOW_STREAMING) { - return physical_plan.Make(data, false); + return make_uniq(physical_plan, data, false); } - return physical_plan.Make(data, false); + return make_uniq(physical_plan, data, false); } // Order-preserving plan, and we can use the batch index: use a batch collector. if (data.output_type == QueryResultOutputType::ALLOW_STREAMING) { - return physical_plan.Make(data); + return make_uniq(physical_plan, data); } - return physical_plan.Make(data); + return make_uniq(physical_plan, data); } vector> PhysicalResultCollector::GetChildren() const { diff --git a/src/duckdb/src/execution/operator/helper/physical_transaction.cpp b/src/duckdb/src/execution/operator/helper/physical_transaction.cpp index 2e75990ca..5ccd901a6 100644 --- a/src/duckdb/src/execution/operator/helper/physical_transaction.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_transaction.cpp @@ -32,6 +32,8 @@ SourceResultType PhysicalTransaction::GetDataInternal(ExecutionContext &context, if (info->modifier == TransactionModifierType::TRANSACTION_READ_ONLY) { client.transaction.SetReadOnly(); } + client.transaction.SetInvalidationPolicy(info->invalidation_policy); + client.transaction.SetAutoRollback(info->auto_rollback); if (Settings::Get(context.client)) { // if immediate transaction mode is enabled then start all transactions immediately auto databases = DatabaseManager::Get(client).GetDatabases(client); diff --git a/src/duckdb/src/function/scalar/list/list_resize.cpp b/src/duckdb/src/function/scalar/list/list_resize.cpp index 19fd149e3..ce39a5171 100644 --- a/src/duckdb/src/function/scalar/list/list_resize.cpp +++ b/src/duckdb/src/function/scalar/list/list_resize.cpp @@ -1,3 +1,4 @@ +#include "duckdb/common/operator/add.hpp" #include "duckdb/common/types/data_chunk.hpp" #include "duckdb/function/scalar/nested_functions.hpp" #include "duckdb/function/scalar/list_functions.hpp" @@ -41,7 +42,8 @@ static void ListResizeFunction(DataChunk &args, ExpressionState &, Vector &resul auto new_size_idx = new_sizes_data.sel->get_index(row_idx); if (lists_data.validity.RowIsValid(list_idx) && new_sizes_data.validity.RowIsValid(new_size_idx)) { - child_vector_size += new_size_entries[new_size_idx]; + child_vector_size = AddOperatorOverflowCheck::Operation( + child_vector_size, new_size_entries[new_size_idx]); } } ListVector::Reserve(result, child_vector_size); diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index 703375990..d5423e33b 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "1-dev332" +#define DUCKDB_PATCH_VERSION "1-dev399" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 5 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 1 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v1.5.1-dev332" +#define DUCKDB_VERSION "v1.5.1-dev399" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "31ea662805" +#define DUCKDB_SOURCE_ID "222ea44eb4" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/include/duckdb/common/arrow/physical_arrow_collector.hpp b/src/duckdb/src/include/duckdb/common/arrow/physical_arrow_collector.hpp index d659235d2..7671f49d0 100644 --- a/src/duckdb/src/include/duckdb/common/arrow/physical_arrow_collector.hpp +++ b/src/duckdb/src/include/duckdb/common/arrow/physical_arrow_collector.hpp @@ -44,7 +44,7 @@ class PhysicalArrowCollector : public PhysicalResultCollector { } public: - static PhysicalOperator &Create(ClientContext &context, PreparedStatementData &data, idx_t batch_size); + static unique_ptr Create(ClientContext &context, PreparedStatementData &data, idx_t batch_size); SinkResultType Sink(ExecutionContext &context, DataChunk &chunk, OperatorSinkInput &input) const override; SinkCombineResultType Combine(ExecutionContext &context, OperatorSinkCombineInput &input) const override; unique_ptr GetResult(GlobalSinkState &state) const override; diff --git a/src/duckdb/src/include/duckdb/common/enum_util.hpp b/src/duckdb/src/include/duckdb/common/enum_util.hpp index 5529a5784..92a6e4f03 100644 --- a/src/duckdb/src/include/duckdb/common/enum_util.hpp +++ b/src/duckdb/src/include/duckdb/common/enum_util.hpp @@ -458,6 +458,8 @@ enum class ThreadPinMode : uint8_t; enum class TimestampCastResult : uint8_t; +enum class TransactionInvalidationPolicy : uint8_t; + enum class TransactionModifierType : uint8_t; enum class TransactionType : uint8_t; @@ -1142,6 +1144,9 @@ const char* EnumUtil::ToChars(ThreadPinMode value); template<> const char* EnumUtil::ToChars(TimestampCastResult value); +template<> +const char* EnumUtil::ToChars(TransactionInvalidationPolicy value); + template<> const char* EnumUtil::ToChars(TransactionModifierType value); @@ -1848,6 +1853,9 @@ ThreadPinMode EnumUtil::FromString(const char *value); template<> TimestampCastResult EnumUtil::FromString(const char *value); +template<> +TransactionInvalidationPolicy EnumUtil::FromString(const char *value); + template<> TransactionModifierType EnumUtil::FromString(const char *value); diff --git a/src/duckdb/src/include/duckdb/common/enums/current_transaction_state.hpp b/src/duckdb/src/include/duckdb/common/enums/current_transaction_state.hpp new file mode 100644 index 000000000..aff42da2a --- /dev/null +++ b/src/duckdb/src/include/duckdb/common/enums/current_transaction_state.hpp @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/current_transaction_state.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +namespace duckdb { + +enum CurrentTransactionState { IN_ACTIVE_TRANSACTION, NOT_IN_ACTIVE_TRANSACTION }; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/executor.hpp b/src/duckdb/src/include/duckdb/execution/executor.hpp index 769626000..46315a989 100644 --- a/src/duckdb/src/include/duckdb/execution/executor.hpp +++ b/src/duckdb/src/include/duckdb/execution/executor.hpp @@ -52,6 +52,7 @@ class Executor { static Executor &Get(ClientContext &context); void Initialize(PhysicalOperator &physical_plan); + void Initialize(unique_ptr physical_plan); void CancelTasks(); PendingExecutionResult ExecuteTask(bool dry_run = false); @@ -147,6 +148,7 @@ class Executor { private: optional_ptr physical_plan; + unique_ptr owned_plan; mutex executor_lock; //! All pipelines of the query plan diff --git a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp index e654a8e9d..c1114b091 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp @@ -32,7 +32,7 @@ class PhysicalResultCollector : public PhysicalOperator { vector names; public: - static PhysicalOperator &GetResultCollector(ClientContext &context, PreparedStatementData &data); + static unique_ptr GetResultCollector(ClientContext &context, PreparedStatementData &data); public: //! The final method used to fetch the query result from this operator diff --git a/src/duckdb/src/include/duckdb/main/client_config.hpp b/src/duckdb/src/include/duckdb/main/client_config.hpp index 40980b8a0..893ddcb31 100644 --- a/src/duckdb/src/include/duckdb/main/client_config.hpp +++ b/src/duckdb/src/include/duckdb/main/client_config.hpp @@ -25,7 +25,8 @@ class ClientContext; class PhysicalResultCollector; class PreparedStatementData; -typedef std::function get_result_collector_t; +typedef std::function(ClientContext &context, PreparedStatementData &data)> + get_result_collector_t; struct ClientConfig { //! If the query profiler is enabled or not. diff --git a/src/duckdb/src/include/duckdb/main/client_context.hpp b/src/duckdb/src/include/duckdb/main/client_context.hpp index e73e60bca..aa077598f 100644 --- a/src/duckdb/src/include/duckdb/main/client_context.hpp +++ b/src/duckdb/src/include/duckdb/main/client_context.hpp @@ -186,7 +186,7 @@ class ClientContext : public enable_shared_from_this { //! Extract the logical plan of a query DUCKDB_API unique_ptr ExtractPlan(const string &query); - DUCKDB_API void HandlePragmaStatements(vector> &statements); + DUCKDB_API void PreprocessStatements(vector> &statements); //! Runs a function with a valid transaction context, potentially starting a transaction if the context is in auto //! commit mode. @@ -311,6 +311,8 @@ class ClientContext : public enable_shared_from_this { unique_ptr statement, PendingQueryParameters parameters); + bool ErrorInvalidatesTransaction(ExceptionType type); + private: //! Lock on using the ClientContext in parallel mutex context_lock; diff --git a/src/duckdb/src/include/duckdb/main/settings.hpp b/src/duckdb/src/include/duckdb/main/settings.hpp index 812565dcd..30a2f3021 100644 --- a/src/duckdb/src/include/duckdb/main/settings.hpp +++ b/src/duckdb/src/include/duckdb/main/settings.hpp @@ -372,6 +372,18 @@ struct CheckpointThresholdSetting { static Value GetSetting(const ClientContext &context); }; +struct CurrentTransactionInvalidationPolicySetting { + using RETURN_TYPE = string; + static constexpr const char *Name = "current_transaction_invalidation_policy"; + static constexpr const char *Description = + "Which types of exceptions invalidate the database for the current transaction"; + static constexpr const char *InputType = "VARCHAR"; + static constexpr const char *DefaultValue = "STANDARD_POLICY"; + static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; + static constexpr idx_t SettingIndex = 16; + static void OnSet(SettingCallbackInfo &info, Value &input); +}; + struct CustomExtensionRepositorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "custom_extension_repository"; @@ -379,7 +391,7 @@ struct CustomExtensionRepositorySetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 16; + static constexpr idx_t SettingIndex = 17; }; struct CustomProfilingSettingsSetting { @@ -409,7 +421,7 @@ struct DebugAsofIejoinSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 17; + static constexpr idx_t SettingIndex = 18; }; struct DebugCheckpointAbortSetting { @@ -420,7 +432,7 @@ struct DebugCheckpointAbortSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "NONE"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 18; + static constexpr idx_t SettingIndex = 19; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -431,7 +443,7 @@ struct DebugCheckpointSleepMsSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "0"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 19; + static constexpr idx_t SettingIndex = 20; }; struct DebugEvictionQueueSleepMicroSecondsSetting { @@ -442,7 +454,7 @@ struct DebugEvictionQueueSleepMicroSecondsSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "0"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 20; + static constexpr idx_t SettingIndex = 21; }; struct DebugForceExternalSetting { @@ -464,7 +476,7 @@ struct DebugForceNoCrossProductSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 21; + static constexpr idx_t SettingIndex = 22; }; struct DebugPhysicalTableScanExecutionStrategySetting { @@ -475,7 +487,7 @@ struct DebugPhysicalTableScanExecutionStrategySetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "DEFAULT"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 22; + static constexpr idx_t SettingIndex = 23; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -486,7 +498,7 @@ struct DebugSkipCheckpointOnCommitSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 23; + static constexpr idx_t SettingIndex = 24; }; struct DebugVerifyBlocksSetting { @@ -496,7 +508,7 @@ struct DebugVerifyBlocksSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 24; + static constexpr idx_t SettingIndex = 25; }; struct DebugVerifyVectorSetting { @@ -506,7 +518,7 @@ struct DebugVerifyVectorSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "NONE"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 25; + static constexpr idx_t SettingIndex = 26; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -517,7 +529,7 @@ struct DebugWindowModeSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "WINDOW"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 26; + static constexpr idx_t SettingIndex = 27; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -529,7 +541,7 @@ struct DefaultBlockSizeSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "262144"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 27; + static constexpr idx_t SettingIndex = 28; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -540,7 +552,7 @@ struct DefaultCollationSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 28; + static constexpr idx_t SettingIndex = 29; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -551,7 +563,7 @@ struct DefaultNullOrderSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "NULLS_LAST"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 29; + static constexpr idx_t SettingIndex = 30; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -562,7 +574,7 @@ struct DefaultOrderSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "ASCENDING"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 30; + static constexpr idx_t SettingIndex = 31; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -583,7 +595,7 @@ struct DeprecatedUsingKeySyntaxSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "DEFAULT"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 31; + static constexpr idx_t SettingIndex = 32; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -596,7 +608,7 @@ struct DisableDatabaseInvalidationSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 32; + static constexpr idx_t SettingIndex = 33; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -607,7 +619,7 @@ struct DisableTimestamptzCastsSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 33; + static constexpr idx_t SettingIndex = 34; }; struct DisabledCompressionMethodsSetting { @@ -657,7 +669,7 @@ struct DuckDBAPISetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 34; + static constexpr idx_t SettingIndex = 35; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -669,7 +681,7 @@ struct DynamicOrFilterThresholdSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "50"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 35; + static constexpr idx_t SettingIndex = 36; }; struct EnableExternalAccessSetting { @@ -681,7 +693,7 @@ struct EnableExternalAccessSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "true"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 36; + static constexpr idx_t SettingIndex = 37; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -692,7 +704,7 @@ struct EnableExternalFileCacheSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "true"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 37; + static constexpr idx_t SettingIndex = 38; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -704,7 +716,7 @@ struct EnableFSSTVectorsSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 38; + static constexpr idx_t SettingIndex = 39; }; struct EnableHTTPLoggingSetting { @@ -724,7 +736,7 @@ struct EnableHTTPMetadataCacheSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 39; + static constexpr idx_t SettingIndex = 40; }; struct EnableLogging { @@ -745,7 +757,7 @@ struct EnableMacroDependenciesSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 40; + static constexpr idx_t SettingIndex = 41; }; struct EnableObjectCacheSetting { @@ -755,7 +767,7 @@ struct EnableObjectCacheSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 41; + static constexpr idx_t SettingIndex = 42; }; struct EnableProfilingSetting { @@ -801,7 +813,7 @@ struct EnableViewDependenciesSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 42; + static constexpr idx_t SettingIndex = 43; }; struct EnabledLogTypes { @@ -821,7 +833,7 @@ struct ErrorsAsJSONSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 43; + static constexpr idx_t SettingIndex = 44; }; struct ExperimentalMetadataReuseSetting { @@ -831,7 +843,7 @@ struct ExperimentalMetadataReuseSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "true"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 44; + static constexpr idx_t SettingIndex = 45; }; struct ExplainOutputSetting { @@ -841,7 +853,7 @@ struct ExplainOutputSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "PHYSICAL_ONLY"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 45; + static constexpr idx_t SettingIndex = 46; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -862,7 +874,7 @@ struct ExtensionDirectorySetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 46; + static constexpr idx_t SettingIndex = 47; }; struct ExternalThreadsSetting { @@ -872,7 +884,7 @@ struct ExternalThreadsSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "1"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 47; + static constexpr idx_t SettingIndex = 48; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -883,7 +895,7 @@ struct FileSearchPathSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 48; + static constexpr idx_t SettingIndex = 49; }; struct ForceBitpackingModeSetting { @@ -893,7 +905,7 @@ struct ForceBitpackingModeSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "AUTO"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 49; + static constexpr idx_t SettingIndex = 50; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -904,7 +916,7 @@ struct ForceCompressionSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "auto"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 50; + static constexpr idx_t SettingIndex = 51; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -937,7 +949,7 @@ struct GeometryMinimumShreddingSize { static constexpr const char *InputType = "BIGINT"; static constexpr const char *DefaultValue = "30000"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 51; + static constexpr idx_t SettingIndex = 52; }; struct HomeDirectorySetting { @@ -947,7 +959,7 @@ struct HomeDirectorySetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 52; + static constexpr idx_t SettingIndex = 53; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -969,7 +981,7 @@ struct HTTPProxySetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 53; + static constexpr idx_t SettingIndex = 54; }; struct HTTPProxyPasswordSetting { @@ -979,7 +991,7 @@ struct HTTPProxyPasswordSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 54; + static constexpr idx_t SettingIndex = 55; }; struct HTTPProxyUsernameSetting { @@ -989,7 +1001,7 @@ struct HTTPProxyUsernameSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 55; + static constexpr idx_t SettingIndex = 56; }; struct IeeeFloatingPointOpsSetting { @@ -1000,7 +1012,7 @@ struct IeeeFloatingPointOpsSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "true"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 56; + static constexpr idx_t SettingIndex = 57; }; struct IgnoreUnknownCrsSetting { @@ -1011,7 +1023,7 @@ struct IgnoreUnknownCrsSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 57; + static constexpr idx_t SettingIndex = 58; }; struct ImmediateTransactionModeSetting { @@ -1022,7 +1034,7 @@ struct ImmediateTransactionModeSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 58; + static constexpr idx_t SettingIndex = 59; }; struct IndexScanMaxCountSetting { @@ -1034,7 +1046,7 @@ struct IndexScanMaxCountSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "2048"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 59; + static constexpr idx_t SettingIndex = 60; }; struct IndexScanPercentageSetting { @@ -1046,7 +1058,7 @@ struct IndexScanPercentageSetting { static constexpr const char *InputType = "DOUBLE"; static constexpr const char *DefaultValue = "0.001"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 60; + static constexpr idx_t SettingIndex = 61; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1058,7 +1070,7 @@ struct IntegerDivisionSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 61; + static constexpr idx_t SettingIndex = 62; }; struct LambdaSyntaxSetting { @@ -1069,7 +1081,7 @@ struct LambdaSyntaxSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "DEFAULT"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 62; + static constexpr idx_t SettingIndex = 63; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1081,7 +1093,7 @@ struct LateMaterializationMaxRowsSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "50"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 63; + static constexpr idx_t SettingIndex = 64; }; struct LockConfigurationSetting { @@ -1091,7 +1103,7 @@ struct LockConfigurationSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 64; + static constexpr idx_t SettingIndex = 65; }; struct LogQueryPathSetting { @@ -1102,7 +1114,7 @@ struct LogQueryPathSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 65; + static constexpr idx_t SettingIndex = 66; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1145,7 +1157,7 @@ struct MaxExpressionDepthSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "1000"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 66; + static constexpr idx_t SettingIndex = 67; }; struct MaxMemorySetting { @@ -1176,7 +1188,7 @@ struct MaxVacuumTasksSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "100"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 67; + static constexpr idx_t SettingIndex = 68; }; struct MergeJoinThresholdSetting { @@ -1186,7 +1198,7 @@ struct MergeJoinThresholdSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "1000"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 68; + static constexpr idx_t SettingIndex = 69; }; struct NestedLoopJoinThresholdSetting { @@ -1197,7 +1209,7 @@ struct NestedLoopJoinThresholdSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "5"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 69; + static constexpr idx_t SettingIndex = 70; }; struct OldImplicitCastingSetting { @@ -1207,7 +1219,7 @@ struct OldImplicitCastingSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 70; + static constexpr idx_t SettingIndex = 71; }; struct OrderByNonIntegerLiteralSetting { @@ -1218,7 +1230,7 @@ struct OrderByNonIntegerLiteralSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 71; + static constexpr idx_t SettingIndex = 72; }; struct OrderedAggregateThresholdSetting { @@ -1228,7 +1240,7 @@ struct OrderedAggregateThresholdSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "262144"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 72; + static constexpr idx_t SettingIndex = 73; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1240,7 +1252,7 @@ struct PartitionedWriteFlushThresholdSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "524288"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 73; + static constexpr idx_t SettingIndex = 74; }; struct PartitionedWriteMaxOpenFilesSetting { @@ -1251,7 +1263,7 @@ struct PartitionedWriteMaxOpenFilesSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "100"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 74; + static constexpr idx_t SettingIndex = 75; }; struct PasswordSetting { @@ -1261,7 +1273,7 @@ struct PasswordSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 75; + static constexpr idx_t SettingIndex = 76; }; struct PerfectHtThresholdSetting { @@ -1271,7 +1283,7 @@ struct PerfectHtThresholdSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "12"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 76; + static constexpr idx_t SettingIndex = 77; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1283,7 +1295,7 @@ struct PinThreadsSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "auto"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 77; + static constexpr idx_t SettingIndex = 78; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1295,7 +1307,7 @@ struct PivotFilterThresholdSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "20"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 78; + static constexpr idx_t SettingIndex = 79; }; struct PivotLimitSetting { @@ -1305,7 +1317,7 @@ struct PivotLimitSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "100000"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 79; + static constexpr idx_t SettingIndex = 80; }; struct PreferRangeJoinsSetting { @@ -1315,7 +1327,7 @@ struct PreferRangeJoinsSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 80; + static constexpr idx_t SettingIndex = 81; }; struct PreserveIdentifierCaseSetting { @@ -1326,7 +1338,7 @@ struct PreserveIdentifierCaseSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "true"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 81; + static constexpr idx_t SettingIndex = 82; }; struct PreserveInsertionOrderSetting { @@ -1338,7 +1350,7 @@ struct PreserveInsertionOrderSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "true"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 82; + static constexpr idx_t SettingIndex = 83; }; struct ProduceArrowStringViewSetting { @@ -1349,7 +1361,7 @@ struct ProduceArrowStringViewSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 83; + static constexpr idx_t SettingIndex = 84; }; struct ProfileOutputSetting { @@ -1402,7 +1414,7 @@ struct ScalarSubqueryErrorOnMultipleRowsSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "true"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = 84; + static constexpr idx_t SettingIndex = 85; }; struct SchedulerProcessPartialSetting { @@ -1417,7 +1429,7 @@ struct SchedulerProcessPartialSetting { static constexpr const char *DefaultValue = "false"; #endif static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 85; + static constexpr idx_t SettingIndex = 86; }; struct SchemaSetting { @@ -1459,7 +1471,7 @@ struct StorageBlockPrefetchSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "REMOTE_ONLY"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 86; + static constexpr idx_t SettingIndex = 87; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1501,7 +1513,7 @@ struct TempFileEncryptionSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 87; + static constexpr idx_t SettingIndex = 88; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1522,7 +1534,7 @@ struct UsernameSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = ""; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 88; + static constexpr idx_t SettingIndex = 89; }; struct ValidateExternalFileCacheSetting { @@ -1534,7 +1546,7 @@ struct ValidateExternalFileCacheSetting { static constexpr const char *InputType = "VARCHAR"; static constexpr const char *DefaultValue = "VALIDATE_ALL"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 89; + static constexpr idx_t SettingIndex = 90; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1546,7 +1558,7 @@ struct VariantMinimumShreddingSizeSetting { static constexpr const char *InputType = "BIGINT"; static constexpr const char *DefaultValue = "30000"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 90; + static constexpr idx_t SettingIndex = 91; }; struct WalAutocheckpointEntriesSetting { @@ -1557,7 +1569,7 @@ struct WalAutocheckpointEntriesSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "0"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 91; + static constexpr idx_t SettingIndex = 92; }; struct WarningsAsErrorsSetting { @@ -1567,7 +1579,7 @@ struct WarningsAsErrorsSetting { static constexpr const char *InputType = "BOOLEAN"; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 92; + static constexpr idx_t SettingIndex = 93; static void OnSet(SettingCallbackInfo &info, Value &input); }; @@ -1579,7 +1591,7 @@ struct WriteBufferRowGroupCountSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "5"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; - static constexpr idx_t SettingIndex = 93; + static constexpr idx_t SettingIndex = 94; }; struct ZstdMinStringLengthSetting { @@ -1590,11 +1602,11 @@ struct ZstdMinStringLengthSetting { static constexpr const char *InputType = "UBIGINT"; static constexpr const char *DefaultValue = "4096"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; - static constexpr idx_t SettingIndex = 94; + static constexpr idx_t SettingIndex = 95; }; struct GeneratedSettingInfo { - static constexpr idx_t MaxSettingIndex = 95; + static constexpr idx_t MaxSettingIndex = 96; }; //===----------------------------------------------------------------------===// diff --git a/src/duckdb/src/include/duckdb/parser/parsed_data/transaction_info.hpp b/src/duckdb/src/include/duckdb/parser/parsed_data/transaction_info.hpp index ffbc5f128..f5ca9731f 100644 --- a/src/duckdb/src/include/duckdb/parser/parsed_data/transaction_info.hpp +++ b/src/duckdb/src/include/duckdb/parser/parsed_data/transaction_info.hpp @@ -20,17 +20,26 @@ enum class TransactionModifierType : uint8_t { TRANSACTION_READ_WRITE }; +enum class TransactionInvalidationPolicy : uint8_t { STANDARD_POLICY, ALL_ERRORS_INVALIDATE_TRANSACTION }; + struct TransactionInfo : public ParseInfo { public: static constexpr const ParseInfoType TYPE = ParseInfoType::TRANSACTION_INFO; public: - explicit TransactionInfo(TransactionType type); + explicit TransactionInfo( + TransactionType type, + TransactionInvalidationPolicy invalidation_policy = TransactionInvalidationPolicy::STANDARD_POLICY, + bool auto_rollback = false); //! The type of transaction statement TransactionType type; //! Whether or not a transaction can make modifications to the database TransactionModifierType modifier; + //! Which types of exceptions invalidate the database + TransactionInvalidationPolicy invalidation_policy; + //! If transaction fails, automatically do a ROLLBACK; + bool auto_rollback; public: void Serialize(Serializer &serializer) const override; diff --git a/src/duckdb/src/include/duckdb/planner/pragma_handler.hpp b/src/duckdb/src/include/duckdb/planner/pragma_handler.hpp deleted file mode 100644 index 361a6a768..000000000 --- a/src/duckdb/src/include/duckdb/planner/pragma_handler.hpp +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/pragma_handler.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/common.hpp" -#include "duckdb/common/vector.hpp" -#include "duckdb/parser/statement/pragma_statement.hpp" - -namespace duckdb { -class ClientContext; -class ClientContextLock; -class SQLStatement; -struct PragmaInfo; - -//! Pragma handler is responsible for converting certain pragma statements into new queries -class PragmaHandler { -public: - explicit PragmaHandler(ClientContext &context); - - void HandlePragmaStatements(ClientContextLock &lock, vector> &statements); - -private: - ClientContext &context; - -private: - //! Handles a pragma statement, returns whether the statement was expanded, if it was expanded the 'resulting_query' - //! contains the statement(s) to replace the current one - bool HandlePragma(SQLStatement &statement, string &resulting_query); - - void HandlePragmaStatementsInternal(vector> &statements); -}; -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/planner/statement_preprocessor.hpp b/src/duckdb/src/include/duckdb/planner/statement_preprocessor.hpp new file mode 100644 index 000000000..be8492f99 --- /dev/null +++ b/src/duckdb/src/include/duckdb/planner/statement_preprocessor.hpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/statement_preprocessor.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/common.hpp" +#include "duckdb/common/vector.hpp" +#include "duckdb/parser/statement/pragma_statement.hpp" +#include "duckdb/transaction/transaction_context.hpp" +#include "duckdb/common/enums/current_transaction_state.hpp" + +namespace duckdb { +class ClientContext; +class ClientContextLock; +class SQLStatement; +struct PragmaInfo; +//! Preprocesses parsed statements: expands pragmas, unpacks multi-statements, and wraps in transactions +class StatementPreprocessor { +public: + explicit StatementPreprocessor(ClientContext &context); + void Preprocess(ClientContextLock &lock, vector> &statements, + CurrentTransactionState transaction_context_state); + void PreprocessInternal(ClientContextLock &lock, vector> &statements, + CurrentTransactionState transaction_context_state); + +private: + ClientContext &context; + +private: + //! Handles a pragma statement, determines whether the statement needs reparsing, if it does, it returns the + //! statement(s) to replace the current one. Otherwise, it just returns back the original statement in a vector. + vector> TryReparsePragma(unique_ptr statement) const; +}; +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/transaction/transaction_context.hpp b/src/duckdb/src/include/duckdb/transaction/transaction_context.hpp index 4c09fb7a9..bb9016145 100644 --- a/src/duckdb/src/include/duckdb/transaction/transaction_context.hpp +++ b/src/duckdb/src/include/duckdb/transaction/transaction_context.hpp @@ -13,6 +13,7 @@ #include "duckdb/common/error_data.hpp" #include "duckdb/common/exception.hpp" #include "duckdb/common/optional_ptr.hpp" +#include "duckdb/parser/parsed_data/transaction_info.hpp" namespace duckdb { @@ -55,9 +56,24 @@ class TransactionContext { void ResetActiveQuery(); void SetActiveQuery(transaction_t query_number); + void SetInvalidationPolicy(TransactionInvalidationPolicy new_invalidation_policy) { + invalidation_policy = new_invalidation_policy; + }; + TransactionInvalidationPolicy GetInvalidationPolicy() { + return invalidation_policy; + }; + void SetAutoRollback(bool new_auto_rollback) { + auto_rollback = new_auto_rollback; + }; + bool GetAutoRollback() { + return auto_rollback; + }; + private: ClientContext &context; bool auto_commit; + TransactionInvalidationPolicy invalidation_policy; + bool auto_rollback; unique_ptr current_transaction; diff --git a/src/duckdb/src/main/client_context.cpp b/src/duckdb/src/main/client_context.cpp index 0c9b1b5d6..073ef1bfe 100644 --- a/src/duckdb/src/main/client_context.cpp +++ b/src/duckdb/src/main/client_context.cpp @@ -43,7 +43,7 @@ #include "duckdb/parser/tableref/column_data_ref.hpp" #include "duckdb/planner/operator/logical_execute.hpp" #include "duckdb/planner/planner.hpp" -#include "duckdb/planner/pragma_handler.hpp" +#include "duckdb/planner/statement_preprocessor.hpp" #include "duckdb/storage/data_table.hpp" #include "duckdb/transaction/meta_transaction.hpp" #include "duckdb/transaction/transaction_context.hpp" @@ -52,6 +52,7 @@ #include "duckdb/logging/log_manager.hpp" #include "duckdb/main/settings.hpp" #include "duckdb/main/result_set_manager.hpp" +#include "duckdb/parser/statement/transaction_statement.hpp" #ifdef __APPLE__ #include @@ -590,9 +591,9 @@ ClientContext::PendingPreparedStatementInternal(ClientContextLock &lock, statement_data.memory_type = parameters.query_parameters.memory_type; // Get the result collector and initialize the executor. - auto &collector = get_collector(*this, statement_data); - D_ASSERT(collector.type == PhysicalOperatorType::RESULT_COLLECTOR); - executor.Initialize(collector); + auto collector = get_collector(*this, statement_data); + D_ASSERT(collector->type == PhysicalOperatorType::RESULT_COLLECTOR); + executor.Initialize(std::move(collector)); auto types = executor.GetTypes(); D_ASSERT(types == statement_data.types); @@ -633,6 +634,15 @@ void ClientContext::WaitForTask(ClientContextLock &lock, BaseQueryResult &result active_query->executor->WaitForTask(); } +bool ClientContext::ErrorInvalidatesTransaction(ExceptionType type) { + switch (transaction.GetInvalidationPolicy()) { + case TransactionInvalidationPolicy::ALL_ERRORS_INVALIDATE_TRANSACTION: + return true; + default: + return Exception::InvalidatesTransaction(type); + } +} + PendingExecutionResult ClientContext::ExecuteTaskInternal(ClientContextLock &lock, BaseQueryResult &result, bool dry_run) { D_ASSERT(active_query); @@ -657,10 +667,10 @@ PendingExecutionResult ClientContext::ExecuteTaskInternal(ClientContextLock &loc } else { // Interrupted by an exception caused in a worker thread error = executor.GetError(); - invalidate_transaction = Exception::InvalidatesTransaction(error.Type()); + invalidate_transaction = ErrorInvalidatesTransaction(error.Type()); result.SetError(error); } - } else if (!Exception::InvalidatesTransaction(error.Type())) { + } else if (!ErrorInvalidatesTransaction(error.Type())) { invalidate_transaction = false; } else if (Exception::InvalidatesDatabase(error.Type()) || error.Type() == ExceptionType::INTERNAL) { // fatal exceptions invalidate the entire database @@ -692,8 +702,11 @@ vector> ClientContext::ParseStatementsInternal(ClientCo Parser parser(GetParserOptions()); parser.ParseQuery(query); - PragmaHandler handler(*this); - handler.HandlePragmaStatements(lock, parser.statements); + StatementPreprocessor preprocessor(*this); + + const CurrentTransactionState transaction_context_state = + transaction.HasActiveTransaction() ? IN_ACTIVE_TRANSACTION : NOT_IN_ACTIVE_TRANSACTION; + preprocessor.Preprocess(lock, parser.statements, transaction_context_state); return std::move(parser.statements); } catch (std::exception &ex) { @@ -703,11 +716,13 @@ vector> ClientContext::ParseStatementsInternal(ClientCo } } -void ClientContext::HandlePragmaStatements(vector> &statements) { +void ClientContext::PreprocessStatements(vector> &statements) { auto lock = LockContext(); - PragmaHandler handler(*this); - handler.HandlePragmaStatements(*lock, statements); + StatementPreprocessor preprocessor(*this); + const CurrentTransactionState transaction_context_state = + transaction.HasActiveTransaction() ? IN_ACTIVE_TRANSACTION : NOT_IN_ACTIVE_TRANSACTION; + preprocessor.Preprocess(*lock, statements, transaction_context_state); } unique_ptr ClientContext::ExtractPlan(const string &query) { @@ -913,10 +928,20 @@ unique_ptr ClientContext::PendingStatementOrPreparedStatemen Parser parser(GetParserOptions()); ErrorData error; parser.ParseQuery(statement->ToString()); + // FIXME: these properties don't round-trip in ToString(), so we overwrite them manually if (statement->type == StatementType::UPDATE_STATEMENT) { // re-apply `prioritize_table_when_binding` (which is normally set during transform) parser.statements[0]->Cast().prioritize_table_when_binding = statement->Cast().prioritize_table_when_binding; + } else if (statement->type == StatementType::TRANSACTION_STATEMENT) { + // re-apply invalidation policy + auto &reparsed_transaction_stmt = parser.statements[0]->Cast(); + auto &previous_transaction_stmt = statement->Cast(); + reparsed_transaction_stmt.info->invalidation_policy = + previous_transaction_stmt.info->invalidation_policy; + // re-apply auto rollback + parser.statements[0]->Cast().info->auto_rollback = + statement->Cast().info->auto_rollback; } statement = std::move(parser.statements[0]); } catch (const NotImplementedException &) { @@ -960,7 +985,7 @@ unique_ptr ClientContext::PendingStatementOrPreparedStatemen } } catch (std::exception &ex) { ErrorData error(ex); - if (!Exception::InvalidatesTransaction(error.Type())) { + if (!ErrorInvalidatesTransaction(error.Type())) { // standard exceptions do not invalidate the current transaction invalidate_query = false; } else if (Exception::InvalidatesDatabase(error.Type())) { @@ -1013,7 +1038,6 @@ unique_ptr ClientContext::Query(unique_ptr statement, unique_ptr ClientContext::Query(const string &query, QueryParameters query_parameters) { auto lock = LockContext(); - vector> statements; try { statements = ParseStatements(*lock, query); @@ -1049,6 +1073,9 @@ unique_ptr ClientContext::Query(const string &query, QueryParameter current_result = ExecutePendingQueryInternal(*lock, *pending_query); } if (current_result->HasError()) { + if (transaction.HasActiveTransaction() && transaction.GetAutoRollback()) { + transaction.Rollback(current_result->GetErrorObject()); + } // Reset the interrupted flag, this was set by the task that found the error // Next statements should not be bothered by that interruption interrupted = false; @@ -1222,7 +1249,7 @@ void ClientContext::RunFunctionInTransactionInternal(ClientContextLock &lock, co } catch (std::exception &ex) { ErrorData error(ex); bool invalidates_transaction = true; - if (!Exception::InvalidatesTransaction(error.Type())) { + if (!ErrorInvalidatesTransaction(error.Type())) { // standard exceptions don't invalidate the transaction invalidates_transaction = false; } else if (Exception::InvalidatesDatabase(error.Type())) { diff --git a/src/duckdb/src/main/config.cpp b/src/duckdb/src/main/config.cpp index 0401d62f9..3d988be58 100644 --- a/src/duckdb/src/main/config.cpp +++ b/src/duckdb/src/main/config.cpp @@ -89,6 +89,7 @@ static const ConfigurationOption internal_options[] = { DUCKDB_GLOBAL(BlockAllocatorMemorySetting), DUCKDB_SETTING(CatalogErrorMaxSchemasSetting), DUCKDB_GLOBAL(CheckpointThresholdSetting), + DUCKDB_SETTING_CALLBACK(CurrentTransactionInvalidationPolicySetting), DUCKDB_SETTING(CustomExtensionRepositorySetting), DUCKDB_LOCAL(CustomProfilingSettingsSetting), DUCKDB_GLOBAL(CustomUserAgentSetting), @@ -204,12 +205,12 @@ static const ConfigurationOption internal_options[] = { DUCKDB_SETTING(ZstdMinStringLengthSetting), FINAL_SETTING}; -static const ConfigurationAlias setting_aliases[] = {DUCKDB_SETTING_ALIAS("memory_limit", 97), - DUCKDB_SETTING_ALIAS("null_order", 41), - DUCKDB_SETTING_ALIAS("profiling_output", 116), - DUCKDB_SETTING_ALIAS("user", 131), +static const ConfigurationAlias setting_aliases[] = {DUCKDB_SETTING_ALIAS("memory_limit", 98), + DUCKDB_SETTING_ALIAS("null_order", 42), + DUCKDB_SETTING_ALIAS("profiling_output", 117), + DUCKDB_SETTING_ALIAS("user", 132), DUCKDB_SETTING_ALIAS("wal_autocheckpoint", 24), - DUCKDB_SETTING_ALIAS("worker_threads", 130), + DUCKDB_SETTING_ALIAS("worker_threads", 131), FINAL_ALIAS}; vector DBConfig::GetOptions() { diff --git a/src/duckdb/src/main/extension/extension_helper.cpp b/src/duckdb/src/main/extension/extension_helper.cpp index 8907b833e..f29532665 100644 --- a/src/duckdb/src/main/extension/extension_helper.cpp +++ b/src/duckdb/src/main/extension/extension_helper.cpp @@ -126,6 +126,8 @@ static const DefaultExtension internal_extensions[] = { {"fts", "Adds support for Full-Text Search Indexes", false}, {"ui", "Adds local UI for DuckDB", false}, {"ducklake", "Adds support for DuckLake, SQL as a Lakehouse Format", false}, + {"vortex", "Adds support for reading and writing files using the Vortex file format", false}, + {"lance", "Adds support for querying Lance datasets", false}, {nullptr, nullptr, false}}; idx_t ExtensionHelper::DefaultExtensionCount() { diff --git a/src/duckdb/src/main/settings/custom_settings.cpp b/src/duckdb/src/main/settings/custom_settings.cpp index 853abd69f..91ef2d454 100644 --- a/src/duckdb/src/main/settings/custom_settings.cpp +++ b/src/duckdb/src/main/settings/custom_settings.cpp @@ -1662,4 +1662,12 @@ void WarningsAsErrorsSetting::OnSet(SettingCallbackInfo &info, Value &input) { } } +void CurrentTransactionInvalidationPolicySetting::OnSet(SettingCallbackInfo &info, Value &input) { + if (!info.context) { + throw InvalidInputException( + "current_transaction_invalidaton_policy can only be set when there is an active client context"); + } + info.context->transaction.SetInvalidationPolicy( + EnumUtil::FromString(input.GetValue())); +} } // namespace duckdb diff --git a/src/duckdb/src/parallel/executor.cpp b/src/duckdb/src/parallel/executor.cpp index 9ab72c3c7..b9cafc8c7 100644 --- a/src/duckdb/src/parallel/executor.cpp +++ b/src/duckdb/src/parallel/executor.cpp @@ -374,6 +374,12 @@ void Executor::VerifyPipelines() { #endif } +void Executor::Initialize(unique_ptr physical_plan_p) { + Reset(); + owned_plan = std::move(physical_plan_p); + InitializeInternal(*owned_plan); +} + void Executor::Initialize(PhysicalOperator &plan) { Reset(); InitializeInternal(plan); diff --git a/src/duckdb/src/parser/parsed_data/transaction_info.cpp b/src/duckdb/src/parser/parsed_data/transaction_info.cpp index af102e6e3..5d5e2e4cf 100644 --- a/src/duckdb/src/parser/parsed_data/transaction_info.cpp +++ b/src/duckdb/src/parser/parsed_data/transaction_info.cpp @@ -6,8 +6,10 @@ namespace duckdb { TransactionInfo::TransactionInfo() : ParseInfo(TYPE) { } -TransactionInfo::TransactionInfo(TransactionType type) - : ParseInfo(TYPE), type(type), modifier(TransactionModifierType::TRANSACTION_DEFAULT_MODIFIER) { +TransactionInfo::TransactionInfo(TransactionType type, TransactionInvalidationPolicy invalidation_policy, + bool auto_rollback) + : ParseInfo(TYPE), type(type), modifier(TransactionModifierType::TRANSACTION_DEFAULT_MODIFIER), + invalidation_policy(invalidation_policy), auto_rollback(auto_rollback) { } string TransactionInfo::ToString() const { @@ -47,6 +49,8 @@ string TransactionInfo::ToString() const { unique_ptr TransactionInfo::Copy() const { auto result = make_uniq(type); result->modifier = modifier; + result->invalidation_policy = invalidation_policy; + result->auto_rollback = auto_rollback; return result; } diff --git a/src/duckdb/src/planner/pragma_handler.cpp b/src/duckdb/src/planner/pragma_handler.cpp deleted file mode 100644 index dda722200..000000000 --- a/src/duckdb/src/planner/pragma_handler.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "duckdb/planner/pragma_handler.hpp" -#include "duckdb/planner/binder.hpp" -#include "duckdb/parser/parser.hpp" - -#include "duckdb/catalog/catalog.hpp" -#include "duckdb/catalog/catalog_entry/pragma_function_catalog_entry.hpp" -#include "duckdb/parser/statement/multi_statement.hpp" -#include "duckdb/parser/parsed_data/bound_pragma_info.hpp" -#include "duckdb/function/function.hpp" - -#include "duckdb/main/client_context.hpp" - -#include "duckdb/common/string_util.hpp" -#include "duckdb/common/file_system.hpp" -#include "duckdb/function/function_binder.hpp" - -namespace duckdb { - -PragmaHandler::PragmaHandler(ClientContext &context) : context(context) { -} - -void PragmaHandler::HandlePragmaStatementsInternal(vector> &statements) { - vector> new_statements; - for (idx_t i = 0; i < statements.size(); i++) { - if (statements[i]->type == StatementType::MULTI_STATEMENT) { - auto &multi_statement = statements[i]->Cast(); - for (auto &stmt : multi_statement.statements) { - new_statements.push_back(std::move(stmt)); - } - continue; - } - if (statements[i]->type == StatementType::PRAGMA_STATEMENT) { - // PRAGMA statement: check if we need to replace it by a new set of statements - PragmaHandler handler(context); - string new_query; - bool expanded = handler.HandlePragma(*statements[i], new_query); - if (expanded) { - // this PRAGMA statement gets replaced by a new query string - // push the new query string through the parser again and add it to the transformer - Parser parser(context.GetParserOptions()); - parser.ParseQuery(new_query); - // insert the new statements and remove the old statement - for (idx_t j = 0; j < parser.statements.size(); j++) { - new_statements.push_back(std::move(parser.statements[j])); - } - continue; - } - } - new_statements.push_back(std::move(statements[i])); - } - statements = std::move(new_statements); -} - -void PragmaHandler::HandlePragmaStatements(ClientContextLock &lock, vector> &statements) { - // first check if there are any pragma statements - bool found_pragma = false; - for (idx_t i = 0; i < statements.size(); i++) { - if (statements[i]->type == StatementType::PRAGMA_STATEMENT || - statements[i]->type == StatementType::MULTI_STATEMENT) { - found_pragma = true; - break; - } - } - if (!found_pragma) { - // no pragmas: skip this step - return; - } - context.RunFunctionInTransactionInternal(lock, [&]() { HandlePragmaStatementsInternal(statements); }); -} - -bool PragmaHandler::HandlePragma(SQLStatement &statement, string &resulting_query) { - auto info = statement.Cast().info->Copy(); - QueryErrorContext error_context(statement.stmt_location); - auto binder = Binder::CreateBinder(context); - auto bound_info = binder->BindPragma(*info, error_context); - if (bound_info->function.query) { - FunctionParameters parameters {bound_info->parameters, bound_info->named_parameters}; - resulting_query = bound_info->function.query(context, parameters); - return true; - } - return false; -} - -} // namespace duckdb diff --git a/src/duckdb/src/planner/statement_preprocessor.cpp b/src/duckdb/src/planner/statement_preprocessor.cpp new file mode 100644 index 000000000..6c541cb68 --- /dev/null +++ b/src/duckdb/src/planner/statement_preprocessor.cpp @@ -0,0 +1,182 @@ +#include "duckdb/planner/statement_preprocessor.hpp" +#include "duckdb/planner/binder.hpp" +#include "duckdb/parser/parser.hpp" + +#include "duckdb/catalog/catalog.hpp" +#include "duckdb/catalog/catalog_entry/pragma_function_catalog_entry.hpp" +#include "duckdb/parser/statement/multi_statement.hpp" +#include "duckdb/parser/parsed_data/bound_pragma_info.hpp" +#include "duckdb/function/function.hpp" + +#include "duckdb/main/client_context.hpp" + +#include "duckdb/common/string_util.hpp" +#include "duckdb/common/file_system.hpp" +#include "duckdb/function/function_binder.hpp" +#include "duckdb/parser/statement/transaction_statement.hpp" +#include "duckdb/parser/expression/constant_expression.hpp" +#include "duckdb/parser/statement/set_statement.hpp" +#include "duckdb/common/enums/current_transaction_state.hpp" + +namespace duckdb { + +enum class PreprocessingTransactionHandling : uint8_t { + // Not in a transaction and should wrap in an implicit BEGIN/COMMIT + WRAP_IN_TRANSACTION, + // Already in an active transaction — set invalidation policy for multi-statement bodies + SET_INVALIDATION_POLICY, + // No transaction handling needed (single statement, or no transaction context applies) + NONE +}; + +void AddStatements(vector> &body_statements, + const PreprocessingTransactionHandling transaction_handling, + vector> &result_statements) { + if (transaction_handling == PreprocessingTransactionHandling::WRAP_IN_TRANSACTION) { + auto begin_info = make_uniq( + TransactionType::BEGIN_TRANSACTION, TransactionInvalidationPolicy::ALL_ERRORS_INVALIDATE_TRANSACTION, true); + result_statements.push_back(make_uniq(std::move(begin_info))); + } else if (transaction_handling == PreprocessingTransactionHandling::SET_INVALIDATION_POLICY) { + // Here we do a `SET current_transaction_invalidation_policy='ALL_ERRORS_INVALIDATE_TRANSACTION';`, for the + // current transaction, to make sure multistatements/pragmas are fully transactional, and invalidate even with + // minor errors such as binder, parser, etc. + result_statements.push_back(make_uniq( + "current_transaction_invalidation_policy", + make_uniq(Value("ALL_ERRORS_INVALIDATE_TRANSACTION")), SetScope::GLOBAL)); + } + // insert body_statements into result_statements + result_statements.insert(result_statements.end(), std::make_move_iterator(body_statements.begin()), + std::make_move_iterator(body_statements.end())); + if (transaction_handling == PreprocessingTransactionHandling::WRAP_IN_TRANSACTION) { + auto commit_info = make_uniq( + TransactionType::COMMIT, TransactionInvalidationPolicy::ALL_ERRORS_INVALIDATE_TRANSACTION, true); + result_statements.push_back(make_uniq(std::move(commit_info))); + } else if (transaction_handling == PreprocessingTransactionHandling::SET_INVALIDATION_POLICY) { + result_statements.push_back( + make_uniq("current_transaction_invalidation_policy", + make_uniq(Value("STANDARD_POLICY")), SetScope::GLOBAL)); + } +} + +StatementPreprocessor::StatementPreprocessor(ClientContext &context) : context(context) { +} + +PreprocessingTransactionHandling GetTransactionHandling(vector> &body_statements, + CurrentTransactionState full_transaction_state, + bool can_wrap = true) { + if (body_statements.size() <= 1) { + return PreprocessingTransactionHandling::NONE; + } + if (full_transaction_state == NOT_IN_ACTIVE_TRANSACTION && can_wrap) { + return PreprocessingTransactionHandling::WRAP_IN_TRANSACTION; + } + if (full_transaction_state == IN_ACTIVE_TRANSACTION) { + return PreprocessingTransactionHandling::SET_INVALIDATION_POLICY; + } + return PreprocessingTransactionHandling::NONE; +} + +void UnpackMultiStatement(MultiStatement &multi_statement, const CurrentTransactionState current_transaction_state, + vector> &new_statements) { +#ifdef DEBUG // MultiStatement should not contain transaction statements + for (auto &sub_statement : multi_statement.statements) { + D_ASSERT(sub_statement->type != StatementType::TRANSACTION_STATEMENT); + } +#endif + bool has_select = false; + for (auto &stmt : multi_statement.statements) { + if (stmt->type == StatementType::SELECT_STATEMENT) { + // Pivot statements have select, and we don't want to wrap those in transactions. + has_select = true; + } + } + bool can_wrap_in_transaction = !has_select; + auto handling = + GetTransactionHandling(multi_statement.statements, current_transaction_state, can_wrap_in_transaction); + AddStatements(multi_statement.statements, handling, new_statements); +} + +vector> StatementPreprocessor::TryReparsePragma(unique_ptr statement) const { + // Try reparsing + const auto info = statement->Cast().info->Copy(); + QueryErrorContext error_context(statement->stmt_location); + const auto binder = Binder::CreateBinder(context); + const auto bound_info = binder->BindPragma(*info, error_context); + if (bound_info->function.query) { + // Needs reparsing + FunctionParameters parameters {bound_info->parameters, bound_info->named_parameters}; + const auto query_to_reparse = bound_info->function.query(context, parameters); + Parser parser(context.GetParserOptions()); + parser.ParseQuery(query_to_reparse); + return std::move(parser.statements); + } + vector> res; + res.push_back(std::move(statement)); + return res; +} + +void StatementPreprocessor::Preprocess(ClientContextLock &lock, vector> &statements, + CurrentTransactionState transaction_context_state) { + // Quick check: do we need preprocessing at all? + bool needs_preprocessing = false; + for (auto &stmt : statements) { + if (stmt->type == StatementType::PRAGMA_STATEMENT || stmt->type == StatementType::MULTI_STATEMENT) { + needs_preprocessing = true; + break; + } + } + if (!needs_preprocessing) { + return; + } + + context.RunFunctionInTransactionInternal(lock, + [&] { PreprocessInternal(lock, statements, transaction_context_state); }); +} + +void StatementPreprocessor::PreprocessInternal(ClientContextLock &lock, vector> &statements, + const CurrentTransactionState transaction_context_state) { + CurrentTransactionState chained_transaction_state = NOT_IN_ACTIVE_TRANSACTION; + vector> new_statements; + for (idx_t i = 0; i < statements.size(); i++) { + auto query = statements[i]->query; + const CurrentTransactionState full_transaction_state = + (transaction_context_state == IN_ACTIVE_TRANSACTION || chained_transaction_state == IN_ACTIVE_TRANSACTION) + ? IN_ACTIVE_TRANSACTION + : NOT_IN_ACTIVE_TRANSACTION; + + switch (statements[i]->type) { + case StatementType::PRAGMA_STATEMENT: { + auto reparsed_statements = TryReparsePragma(std::move(statements[i])); + const auto handling = GetTransactionHandling(reparsed_statements, full_transaction_state); + AddStatements(reparsed_statements, handling, new_statements); + break; + } + case StatementType::MULTI_STATEMENT: { + auto &multi_statement = statements[i]->Cast(); + UnpackMultiStatement(multi_statement, full_transaction_state, new_statements); + break; + } + case StatementType::TRANSACTION_STATEMENT: { + auto &transaction_stmt = statements[i]->Cast(); + + if (transaction_stmt.info->type == TransactionType::BEGIN_TRANSACTION) { + new_statements.push_back(std::move(statements[i])); + chained_transaction_state = IN_ACTIVE_TRANSACTION; + break; + } + if (transaction_stmt.info->type == TransactionType::COMMIT || + transaction_stmt.info->type == TransactionType::ROLLBACK) { + chained_transaction_state = NOT_IN_ACTIVE_TRANSACTION; + } + new_statements.push_back(std::move(statements[i])); + break; + } + default: { + new_statements.push_back(std::move(statements[i])); + } + } + } + + statements = std::move(new_statements); +} +} // namespace duckdb diff --git a/src/duckdb/src/storage/serialization/serialize_parse_info.cpp b/src/duckdb/src/storage/serialization/serialize_parse_info.cpp index e5ffc2c45..a0f5edd30 100644 --- a/src/duckdb/src/storage/serialization/serialize_parse_info.cpp +++ b/src/duckdb/src/storage/serialization/serialize_parse_info.cpp @@ -656,12 +656,16 @@ void TransactionInfo::Serialize(Serializer &serializer) const { ParseInfo::Serialize(serializer); serializer.WriteProperty(200, "type", type); serializer.WriteProperty(201, "modifier", modifier); + serializer.WritePropertyWithDefault(202, "invalidation_policy", invalidation_policy, TransactionInvalidationPolicy::STANDARD_POLICY); + serializer.WritePropertyWithDefault(203, "auto_rollback", auto_rollback); } unique_ptr TransactionInfo::Deserialize(Deserializer &deserializer) { auto result = duckdb::unique_ptr(new TransactionInfo()); deserializer.ReadProperty(200, "type", result->type); deserializer.ReadProperty(201, "modifier", result->modifier); + deserializer.ReadPropertyWithExplicitDefault(202, "invalidation_policy", result->invalidation_policy, TransactionInvalidationPolicy::STANDARD_POLICY); + deserializer.ReadPropertyWithDefault(203, "auto_rollback", result->auto_rollback); return std::move(result); } diff --git a/src/duckdb/ub_src_planner.cpp b/src/duckdb/ub_src_planner.cpp index 729cee88e..fa5f6346d 100644 --- a/src/duckdb/ub_src_planner.cpp +++ b/src/duckdb/ub_src_planner.cpp @@ -24,7 +24,7 @@ #include "src/planner/planner.cpp" -#include "src/planner/pragma_handler.cpp" +#include "src/planner/statement_preprocessor.cpp" #include "src/planner/logical_operator_deep_copy.cpp"