duckdb 0.3.2-dev633.0 → 0.3.2-dev656.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +795 -493
- package/src/duckdb.hpp +5863 -5641
package/src/duckdb.cpp
CHANGED
|
@@ -7200,7 +7200,7 @@ int ResultArrowArrayStreamWrapper::MyStreamGetSchema(struct ArrowArrayStream *st
|
|
|
7200
7200
|
}
|
|
7201
7201
|
if (result.type == QueryResultType::STREAM_RESULT) {
|
|
7202
7202
|
auto &stream_result = (StreamQueryResult &)result;
|
|
7203
|
-
if (!stream_result.
|
|
7203
|
+
if (!stream_result.IsOpen()) {
|
|
7204
7204
|
my_stream->last_error = "Query Stream is closed";
|
|
7205
7205
|
return -1;
|
|
7206
7206
|
}
|
|
@@ -7221,7 +7221,7 @@ int ResultArrowArrayStreamWrapper::MyStreamGetNext(struct ArrowArrayStream *stre
|
|
|
7221
7221
|
}
|
|
7222
7222
|
if (result.type == QueryResultType::STREAM_RESULT) {
|
|
7223
7223
|
auto &stream_result = (StreamQueryResult &)result;
|
|
7224
|
-
if (!stream_result.
|
|
7224
|
+
if (!stream_result.IsOpen()) {
|
|
7225
7225
|
my_stream->last_error = "Query Stream is closed";
|
|
7226
7226
|
return -1;
|
|
7227
7227
|
}
|
|
@@ -24080,51 +24080,43 @@ bool Printer::IsTerminal() {
|
|
|
24080
24080
|
|
|
24081
24081
|
namespace duckdb {
|
|
24082
24082
|
|
|
24083
|
-
|
|
24084
|
-
|
|
24085
|
-
WaitFor(std::chrono::milliseconds(show_progress_after));
|
|
24086
|
-
while (!stop) {
|
|
24087
|
-
int new_percentage;
|
|
24088
|
-
supported = executor->GetPipelinesProgress(new_percentage);
|
|
24089
|
-
current_percentage = new_percentage;
|
|
24090
|
-
if (supported && current_percentage > -1 && ClientConfig::GetConfig(executor->context).print_progress_bar) {
|
|
24091
|
-
Printer::PrintProgress(current_percentage, PROGRESS_BAR_STRING.c_str(), PROGRESS_BAR_WIDTH);
|
|
24092
|
-
}
|
|
24093
|
-
WaitFor(std::chrono::milliseconds(time_update_bar));
|
|
24094
|
-
}
|
|
24095
|
-
#endif
|
|
24083
|
+
ProgressBar::ProgressBar(Executor &executor, idx_t show_progress_after)
|
|
24084
|
+
: executor(executor), show_progress_after(show_progress_after), current_percentage(-1) {
|
|
24096
24085
|
}
|
|
24097
24086
|
|
|
24098
|
-
|
|
24087
|
+
double ProgressBar::GetCurrentPercentage() {
|
|
24099
24088
|
return current_percentage;
|
|
24100
24089
|
}
|
|
24101
24090
|
|
|
24102
24091
|
void ProgressBar::Start() {
|
|
24103
|
-
|
|
24104
|
-
Stop(false);
|
|
24105
|
-
stop = false;
|
|
24092
|
+
profiler.Start();
|
|
24106
24093
|
current_percentage = 0;
|
|
24107
|
-
|
|
24108
|
-
#endif
|
|
24094
|
+
supported = true;
|
|
24109
24095
|
}
|
|
24110
24096
|
|
|
24111
|
-
ProgressBar
|
|
24112
|
-
|
|
24113
|
-
|
|
24114
|
-
|
|
24115
|
-
|
|
24116
|
-
|
|
24117
|
-
if (
|
|
24118
|
-
|
|
24119
|
-
|
|
24120
|
-
|
|
24121
|
-
|
|
24122
|
-
|
|
24097
|
+
void ProgressBar::Update(bool final) {
|
|
24098
|
+
if (!supported) {
|
|
24099
|
+
return;
|
|
24100
|
+
}
|
|
24101
|
+
double new_percentage;
|
|
24102
|
+
supported = executor.GetPipelinesProgress(new_percentage);
|
|
24103
|
+
if (!supported) {
|
|
24104
|
+
return;
|
|
24105
|
+
}
|
|
24106
|
+
auto sufficient_time_elapsed = profiler.Elapsed() > show_progress_after / 1000.0;
|
|
24107
|
+
auto print_progress = ClientConfig::GetConfig(executor.context).print_progress_bar;
|
|
24108
|
+
if (new_percentage > current_percentage) {
|
|
24109
|
+
current_percentage = new_percentage;
|
|
24110
|
+
}
|
|
24111
|
+
if (supported && print_progress && sufficient_time_elapsed && current_percentage > -1 && print_progress) {
|
|
24112
|
+
if (final) {
|
|
24123
24113
|
Printer::FinishProgressBarPrint(PROGRESS_BAR_STRING.c_str(), PROGRESS_BAR_WIDTH);
|
|
24114
|
+
} else {
|
|
24115
|
+
Printer::PrintProgress(current_percentage, PROGRESS_BAR_STRING.c_str(), PROGRESS_BAR_WIDTH);
|
|
24124
24116
|
}
|
|
24125
24117
|
}
|
|
24126
|
-
#endif
|
|
24127
24118
|
}
|
|
24119
|
+
|
|
24128
24120
|
} // namespace duckdb
|
|
24129
24121
|
|
|
24130
24122
|
|
|
@@ -30394,54 +30386,6 @@ string StringUtil::CandidatesErrorMessage(const vector<string> &strings, const s
|
|
|
30394
30386
|
|
|
30395
30387
|
|
|
30396
30388
|
|
|
30397
|
-
//===----------------------------------------------------------------------===//
|
|
30398
|
-
// DuckDB
|
|
30399
|
-
//
|
|
30400
|
-
// duckdb/common/profiler.hpp
|
|
30401
|
-
//
|
|
30402
|
-
//
|
|
30403
|
-
//===----------------------------------------------------------------------===//
|
|
30404
|
-
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
|
|
30408
|
-
|
|
30409
|
-
|
|
30410
|
-
namespace duckdb {
|
|
30411
|
-
|
|
30412
|
-
//! The profiler can be used to measure elapsed time
|
|
30413
|
-
template <typename T>
|
|
30414
|
-
class Profiler {
|
|
30415
|
-
public:
|
|
30416
|
-
//! Starts the timer
|
|
30417
|
-
void Start() {
|
|
30418
|
-
finished = false;
|
|
30419
|
-
start = Tick();
|
|
30420
|
-
}
|
|
30421
|
-
//! Finishes timing
|
|
30422
|
-
void End() {
|
|
30423
|
-
end = Tick();
|
|
30424
|
-
finished = true;
|
|
30425
|
-
}
|
|
30426
|
-
|
|
30427
|
-
//! Returns the elapsed time in seconds. If End() has been called, returns
|
|
30428
|
-
//! the total elapsed time. Otherwise returns how far along the timer is
|
|
30429
|
-
//! right now.
|
|
30430
|
-
double Elapsed() const {
|
|
30431
|
-
auto _end = finished ? end : Tick();
|
|
30432
|
-
return std::chrono::duration_cast<std::chrono::duration<double>>(_end - start).count();
|
|
30433
|
-
}
|
|
30434
|
-
|
|
30435
|
-
private:
|
|
30436
|
-
time_point<T> Tick() const {
|
|
30437
|
-
return T::now();
|
|
30438
|
-
}
|
|
30439
|
-
time_point<T> start;
|
|
30440
|
-
time_point<T> end;
|
|
30441
|
-
bool finished = false;
|
|
30442
|
-
};
|
|
30443
|
-
|
|
30444
|
-
} // namespace duckdb
|
|
30445
30389
|
|
|
30446
30390
|
|
|
30447
30391
|
|
|
@@ -30454,6 +30398,7 @@ private:
|
|
|
30454
30398
|
|
|
30455
30399
|
|
|
30456
30400
|
namespace duckdb {
|
|
30401
|
+
class ClientContext;
|
|
30457
30402
|
class ExpressionExecutor;
|
|
30458
30403
|
class PhysicalOperator;
|
|
30459
30404
|
class SQLStatement;
|
|
@@ -30545,7 +30490,7 @@ private:
|
|
|
30545
30490
|
//! Whether or not the profiler is enabled
|
|
30546
30491
|
bool enabled;
|
|
30547
30492
|
//! The timer used to time the execution time of the individual Physical Operators
|
|
30548
|
-
Profiler
|
|
30493
|
+
Profiler op;
|
|
30549
30494
|
//! The stack of Physical Operators that are currently active
|
|
30550
30495
|
const PhysicalOperator *active_operator;
|
|
30551
30496
|
//! A mapping of physical operators to recorded timings
|
|
@@ -30555,17 +30500,7 @@ private:
|
|
|
30555
30500
|
//! The QueryProfiler can be used to measure timings of queries
|
|
30556
30501
|
class QueryProfiler {
|
|
30557
30502
|
public:
|
|
30558
|
-
DUCKDB_API QueryProfiler()
|
|
30559
|
-
: automatic_print_format(ProfilerPrintFormat::NONE), enabled(false), detailed_enabled(false), running(false),
|
|
30560
|
-
query_requires_profiling(false), is_explain_analyze(false), stored_enabled(false),
|
|
30561
|
-
stored_automatic_print_format(ProfilerPrintFormat::NONE) {
|
|
30562
|
-
}
|
|
30563
|
-
|
|
30564
|
-
//! The format to automatically print query profiling information in (default: disabled)
|
|
30565
|
-
ProfilerPrintFormat automatic_print_format;
|
|
30566
|
-
//! The file to save query profiling information to, instead of printing it to the console (empty = print to
|
|
30567
|
-
//! console)
|
|
30568
|
-
string save_location;
|
|
30503
|
+
DUCKDB_API QueryProfiler(ClientContext &context);
|
|
30569
30504
|
|
|
30570
30505
|
public:
|
|
30571
30506
|
struct TreeNode {
|
|
@@ -30589,26 +30524,12 @@ private:
|
|
|
30589
30524
|
mutex flush_lock;
|
|
30590
30525
|
|
|
30591
30526
|
public:
|
|
30592
|
-
DUCKDB_API
|
|
30593
|
-
|
|
30594
|
-
|
|
30595
|
-
|
|
30596
|
-
|
|
30597
|
-
DUCKDB_API void DetailedEnable() {
|
|
30598
|
-
detailed_enabled = true;
|
|
30599
|
-
}
|
|
30527
|
+
DUCKDB_API bool IsEnabled() const;
|
|
30528
|
+
DUCKDB_API bool IsDetailedEnabled() const;
|
|
30529
|
+
DUCKDB_API ProfilerPrintFormat GetPrintFormat() const;
|
|
30530
|
+
DUCKDB_API string GetSaveLocation() const;
|
|
30600
30531
|
|
|
30601
|
-
DUCKDB_API
|
|
30602
|
-
enabled = false;
|
|
30603
|
-
}
|
|
30604
|
-
|
|
30605
|
-
DUCKDB_API bool IsEnabled() {
|
|
30606
|
-
return enabled;
|
|
30607
|
-
}
|
|
30608
|
-
|
|
30609
|
-
bool IsDetailedEnabled() const {
|
|
30610
|
-
return detailed_enabled;
|
|
30611
|
-
}
|
|
30532
|
+
DUCKDB_API static QueryProfiler &Get(ClientContext &context);
|
|
30612
30533
|
|
|
30613
30534
|
DUCKDB_API void StartQuery(string query, bool is_explain_analyze = false);
|
|
30614
30535
|
DUCKDB_API void EndQuery();
|
|
@@ -30637,13 +30558,12 @@ public:
|
|
|
30637
30558
|
void Finalize(TreeNode &node);
|
|
30638
30559
|
|
|
30639
30560
|
private:
|
|
30640
|
-
|
|
30641
|
-
|
|
30642
|
-
//! Whether or not detailed query profiling is enabled
|
|
30643
|
-
bool detailed_enabled;
|
|
30561
|
+
ClientContext &context;
|
|
30562
|
+
|
|
30644
30563
|
//! Whether or not the query profiler is running
|
|
30645
30564
|
bool running;
|
|
30646
30565
|
|
|
30566
|
+
//! Whether or not the query requires profiling
|
|
30647
30567
|
bool query_requires_profiling;
|
|
30648
30568
|
|
|
30649
30569
|
//! The root of the query tree
|
|
@@ -30651,14 +30571,11 @@ private:
|
|
|
30651
30571
|
//! The query string
|
|
30652
30572
|
string query;
|
|
30653
30573
|
//! The timer used to time the execution time of the entire query
|
|
30654
|
-
Profiler
|
|
30574
|
+
Profiler main_query;
|
|
30655
30575
|
//! A map of a Physical Operator pointer to a tree node
|
|
30656
30576
|
TreeMap tree_map;
|
|
30657
30577
|
|
|
30658
30578
|
bool is_explain_analyze;
|
|
30659
|
-
bool stored_enabled;
|
|
30660
|
-
ProfilerPrintFormat stored_automatic_print_format;
|
|
30661
|
-
string stored_save_location;
|
|
30662
30579
|
|
|
30663
30580
|
public:
|
|
30664
30581
|
const TreeMap &GetTreeMap() const {
|
|
@@ -30667,7 +30584,7 @@ public:
|
|
|
30667
30584
|
|
|
30668
30585
|
private:
|
|
30669
30586
|
//! The timer used to time the individual phases of the planning process
|
|
30670
|
-
Profiler
|
|
30587
|
+
Profiler phase_profiler;
|
|
30671
30588
|
//! A mapping of the phase names to the timings
|
|
30672
30589
|
using PhaseTimingStorage = unordered_map<string, double>;
|
|
30673
30590
|
PhaseTimingStorage phase_timings;
|
|
@@ -41627,12 +41544,15 @@ static bool TemplatedBooleanOperation(const Value &left, const Value &right) {
|
|
|
41627
41544
|
const auto &left_type = left.type();
|
|
41628
41545
|
const auto &right_type = right.type();
|
|
41629
41546
|
if (left_type != right_type) {
|
|
41630
|
-
|
|
41631
|
-
|
|
41632
|
-
|
|
41633
|
-
|
|
41547
|
+
Value left_copy = left;
|
|
41548
|
+
Value right_copy = right;
|
|
41549
|
+
|
|
41550
|
+
LogicalType comparison_type = BoundComparisonExpression::BindComparison(left_type, right_type);
|
|
41551
|
+
if (!left_copy.TryCastAs(comparison_type) || !right_copy.TryCastAs(comparison_type)) {
|
|
41634
41552
|
return false;
|
|
41635
41553
|
}
|
|
41554
|
+
D_ASSERT(left_copy.type() == right_copy.type());
|
|
41555
|
+
return TemplatedBooleanOperation<OP>(left_copy, right_copy);
|
|
41636
41556
|
}
|
|
41637
41557
|
switch (left_type.InternalType()) {
|
|
41638
41558
|
case PhysicalType::BOOL:
|
|
@@ -52680,8 +52600,9 @@ void PhysicalSimpleAggregate::Combine(ExecutionContext &context, GlobalSinkState
|
|
|
52680
52600
|
aggregate.function.combine(source_state, dest_state, 1);
|
|
52681
52601
|
}
|
|
52682
52602
|
|
|
52603
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
52683
52604
|
context.thread.profiler.Flush(this, &source.child_executor, "child_executor", 0);
|
|
52684
|
-
|
|
52605
|
+
client_profiler.Flush(context.thread.profiler);
|
|
52685
52606
|
}
|
|
52686
52607
|
|
|
52687
52608
|
SinkFinalizeType PhysicalSimpleAggregate::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
@@ -54486,7 +54407,8 @@ SinkResultType PhysicalExplainAnalyze::Sink(ExecutionContext &context, GlobalSin
|
|
|
54486
54407
|
SinkFinalizeType PhysicalExplainAnalyze::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
54487
54408
|
GlobalSinkState &gstate_p) const {
|
|
54488
54409
|
auto &gstate = (ExplainAnalyzeStateGlobalState &)gstate_p;
|
|
54489
|
-
|
|
54410
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
54411
|
+
gstate.analyzed_plan = profiler.ToString();
|
|
54490
54412
|
return SinkFinalizeType::READY;
|
|
54491
54413
|
}
|
|
54492
54414
|
|
|
@@ -57267,8 +57189,9 @@ SinkResultType PhysicalHashJoin::Sink(ExecutionContext &context, GlobalSinkState
|
|
|
57267
57189
|
|
|
57268
57190
|
void PhysicalHashJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
57269
57191
|
auto &state = (HashJoinLocalState &)lstate;
|
|
57192
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
57270
57193
|
context.thread.profiler.Flush(this, &state.build_executor, "build_executor", 1);
|
|
57271
|
-
|
|
57194
|
+
client_profiler.Flush(context.thread.profiler);
|
|
57272
57195
|
}
|
|
57273
57196
|
|
|
57274
57197
|
//===--------------------------------------------------------------------===//
|
|
@@ -58032,8 +57955,10 @@ SinkResultType PhysicalNestedLoopJoin::Sink(ExecutionContext &context, GlobalSin
|
|
|
58032
57955
|
|
|
58033
57956
|
void PhysicalNestedLoopJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
58034
57957
|
auto &state = (NestedLoopJoinLocalState &)lstate;
|
|
57958
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
57959
|
+
|
|
58035
57960
|
context.thread.profiler.Flush(this, &state.rhs_executor, "rhs_executor", 1);
|
|
58036
|
-
|
|
57961
|
+
client_profiler.Flush(context.thread.profiler);
|
|
58037
57962
|
}
|
|
58038
57963
|
|
|
58039
57964
|
SinkFinalizeType PhysicalNestedLoopJoin::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
@@ -58465,8 +58390,10 @@ SinkResultType PhysicalPiecewiseMergeJoin::Sink(ExecutionContext &context, Globa
|
|
|
58465
58390
|
void PhysicalPiecewiseMergeJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate,
|
|
58466
58391
|
LocalSinkState &lstate) const {
|
|
58467
58392
|
auto &state = (MergeJoinLocalState &)lstate;
|
|
58393
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
58394
|
+
|
|
58468
58395
|
context.thread.profiler.Flush(this, &state.rhs_executor, "rhs_executor", 1);
|
|
58469
|
-
|
|
58396
|
+
client_profiler.Flush(context.thread.profiler);
|
|
58470
58397
|
}
|
|
58471
58398
|
|
|
58472
58399
|
//===--------------------------------------------------------------------===//
|
|
@@ -59051,12 +58978,13 @@ public:
|
|
|
59051
58978
|
: ExecutorTask(context), event(move(event_p)), context(context), state(state) {
|
|
59052
58979
|
}
|
|
59053
58980
|
|
|
59054
|
-
|
|
58981
|
+
TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override {
|
|
59055
58982
|
// Initialize merge sorted and iterate until done
|
|
59056
58983
|
auto &global_sort_state = state.global_sort_state;
|
|
59057
58984
|
MergeSorter merge_sorter(global_sort_state, BufferManager::GetBufferManager(context));
|
|
59058
58985
|
merge_sorter.PerformInMergeRound();
|
|
59059
58986
|
event->FinishTask();
|
|
58987
|
+
return TaskExecutionResult::TASK_FINISHED;
|
|
59060
58988
|
}
|
|
59061
58989
|
|
|
59062
58990
|
private:
|
|
@@ -62392,8 +62320,9 @@ unique_ptr<LocalSinkState> PhysicalInsert::GetLocalSinkState(ExecutionContext &c
|
|
|
62392
62320
|
|
|
62393
62321
|
void PhysicalInsert::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
62394
62322
|
auto &state = (InsertLocalState &)lstate;
|
|
62323
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
62395
62324
|
context.thread.profiler.Flush(this, &state.default_executor, "default_executor", 1);
|
|
62396
|
-
|
|
62325
|
+
client_profiler.Flush(context.thread.profiler);
|
|
62397
62326
|
}
|
|
62398
62327
|
|
|
62399
62328
|
//===--------------------------------------------------------------------===//
|
|
@@ -62599,8 +62528,9 @@ unique_ptr<LocalSinkState> PhysicalUpdate::GetLocalSinkState(ExecutionContext &c
|
|
|
62599
62528
|
|
|
62600
62529
|
void PhysicalUpdate::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
62601
62530
|
auto &state = (UpdateLocalState &)lstate;
|
|
62531
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
62602
62532
|
context.thread.profiler.Flush(this, &state.default_executor, "default_executor", 1);
|
|
62603
|
-
|
|
62533
|
+
client_profiler.Flush(context.thread.profiler);
|
|
62604
62534
|
}
|
|
62605
62535
|
|
|
62606
62536
|
//===--------------------------------------------------------------------===//
|
|
@@ -68596,25 +68526,27 @@ private:
|
|
|
68596
68526
|
};
|
|
68597
68527
|
|
|
68598
68528
|
unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(unique_ptr<LogicalOperator> op) {
|
|
68529
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
68530
|
+
|
|
68599
68531
|
// first resolve column references
|
|
68600
|
-
|
|
68532
|
+
profiler.StartPhase("column_binding");
|
|
68601
68533
|
ColumnBindingResolver resolver;
|
|
68602
68534
|
resolver.VisitOperator(*op);
|
|
68603
|
-
|
|
68535
|
+
profiler.EndPhase();
|
|
68604
68536
|
|
|
68605
68537
|
// now resolve types of all the operators
|
|
68606
|
-
|
|
68538
|
+
profiler.StartPhase("resolve_types");
|
|
68607
68539
|
op->ResolveOperatorTypes();
|
|
68608
|
-
|
|
68540
|
+
profiler.EndPhase();
|
|
68609
68541
|
|
|
68610
68542
|
// extract dependencies from the logical plan
|
|
68611
68543
|
DependencyExtractor extractor(dependencies);
|
|
68612
68544
|
extractor.VisitOperator(*op);
|
|
68613
68545
|
|
|
68614
68546
|
// then create the main physical plan
|
|
68615
|
-
|
|
68547
|
+
profiler.StartPhase("create_plan");
|
|
68616
68548
|
auto plan = CreatePlan(*op);
|
|
68617
|
-
|
|
68549
|
+
profiler.EndPhase();
|
|
68618
68550
|
return plan;
|
|
68619
68551
|
}
|
|
68620
68552
|
|
|
@@ -68976,6 +68908,7 @@ public:
|
|
|
68976
68908
|
idx_t radix_p)
|
|
68977
68909
|
: ExecutorTask(executor), event(move(event_p)), state(state_p), radix(radix_p) {
|
|
68978
68910
|
}
|
|
68911
|
+
|
|
68979
68912
|
static void FinalizeHT(RadixHTGlobalState &gstate, idx_t radix) {
|
|
68980
68913
|
D_ASSERT(gstate.partition_info.n_partitions <= gstate.finalized_hts.size());
|
|
68981
68914
|
D_ASSERT(gstate.finalized_hts[radix]);
|
|
@@ -68988,9 +68921,10 @@ public:
|
|
|
68988
68921
|
gstate.finalized_hts[radix]->Finalize();
|
|
68989
68922
|
}
|
|
68990
68923
|
|
|
68991
|
-
|
|
68924
|
+
TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override {
|
|
68992
68925
|
FinalizeHT(state, radix);
|
|
68993
68926
|
event->FinishTask();
|
|
68927
|
+
return TaskExecutionResult::TASK_FINISHED;
|
|
68994
68928
|
}
|
|
68995
68929
|
|
|
68996
68930
|
private:
|
|
@@ -78092,8 +78026,9 @@ struct PragmaFunctions {
|
|
|
78092
78026
|
namespace duckdb {
|
|
78093
78027
|
|
|
78094
78028
|
static void PragmaEnableProfilingStatement(ClientContext &context, const FunctionParameters ¶meters) {
|
|
78095
|
-
|
|
78096
|
-
|
|
78029
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
78030
|
+
config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE;
|
|
78031
|
+
config.enable_profiler = true;
|
|
78097
78032
|
}
|
|
78098
78033
|
|
|
78099
78034
|
void RegisterEnableProfiling(BuiltinFunctions &set) {
|
|
@@ -78105,8 +78040,9 @@ void RegisterEnableProfiling(BuiltinFunctions &set) {
|
|
|
78105
78040
|
}
|
|
78106
78041
|
|
|
78107
78042
|
static void PragmaDisableProfiling(ClientContext &context, const FunctionParameters ¶meters) {
|
|
78108
|
-
context
|
|
78109
|
-
|
|
78043
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
78044
|
+
config.enable_profiler = false;
|
|
78045
|
+
config.profiler_print_format = ProfilerPrintFormat::NONE;
|
|
78110
78046
|
}
|
|
78111
78047
|
|
|
78112
78048
|
static void PragmaEnableProgressBar(ClientContext &context, const FunctionParameters ¶meters) {
|
|
@@ -91738,8 +91674,7 @@ unique_ptr<FunctionData> BindSystemFunction(ClientContext &context, ScalarFuncti
|
|
|
91738
91674
|
|
|
91739
91675
|
static void CurrentQueryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
91740
91676
|
auto &info = SystemBindData::GetFrom(state);
|
|
91741
|
-
|
|
91742
|
-
Value val(info.context.query);
|
|
91677
|
+
Value val(info.context.GetCurrentQuery());
|
|
91743
91678
|
result.Reference(val);
|
|
91744
91679
|
}
|
|
91745
91680
|
|
|
@@ -91981,6 +91916,21 @@ void ScalarFunction::NopFunction(DataChunk &input, ExpressionState &state, Vecto
|
|
|
91981
91916
|
|
|
91982
91917
|
|
|
91983
91918
|
|
|
91919
|
+
//===----------------------------------------------------------------------===//
|
|
91920
|
+
// DuckDB
|
|
91921
|
+
//
|
|
91922
|
+
// duckdb/common/thread.hpp
|
|
91923
|
+
//
|
|
91924
|
+
//
|
|
91925
|
+
//===----------------------------------------------------------------------===//
|
|
91926
|
+
|
|
91927
|
+
|
|
91928
|
+
|
|
91929
|
+
#include <thread>
|
|
91930
|
+
|
|
91931
|
+
namespace duckdb {
|
|
91932
|
+
using std::thread;
|
|
91933
|
+
}
|
|
91984
91934
|
|
|
91985
91935
|
#include <map>
|
|
91986
91936
|
#include <condition_variable>
|
|
@@ -92126,7 +92076,7 @@ private:
|
|
|
92126
92076
|
//! Gets Arrow Table's Cardinality
|
|
92127
92077
|
static unique_ptr<NodeStatistics> ArrowScanCardinality(ClientContext &context, const FunctionData *bind_data);
|
|
92128
92078
|
//! Gets the progress on the table scan, used for Progress Bars
|
|
92129
|
-
static
|
|
92079
|
+
static double ArrowProgress(ClientContext &context, const FunctionData *bind_data_p);
|
|
92130
92080
|
};
|
|
92131
92081
|
|
|
92132
92082
|
} // namespace duckdb
|
|
@@ -93225,12 +93175,12 @@ unique_ptr<NodeStatistics> ArrowTableFunction::ArrowScanCardinality(ClientContex
|
|
|
93225
93175
|
return make_unique<NodeStatistics>(bind_data.number_of_rows, bind_data.number_of_rows);
|
|
93226
93176
|
}
|
|
93227
93177
|
|
|
93228
|
-
|
|
93178
|
+
double ArrowTableFunction::ArrowProgress(ClientContext &context, const FunctionData *bind_data_p) {
|
|
93229
93179
|
auto &bind_data = (const ArrowScanFunctionData &)*bind_data_p;
|
|
93230
93180
|
if (bind_data.number_of_rows == 0) {
|
|
93231
93181
|
return 100;
|
|
93232
93182
|
}
|
|
93233
|
-
auto percentage = bind_data.lines_read * 100 / bind_data.number_of_rows;
|
|
93183
|
+
auto percentage = bind_data.lines_read * 100.0 / bind_data.number_of_rows;
|
|
93234
93184
|
return percentage;
|
|
93235
93185
|
}
|
|
93236
93186
|
|
|
@@ -94915,12 +94865,12 @@ static void ReadCSVAddNamedParameters(TableFunction &table_function) {
|
|
|
94915
94865
|
table_function.named_parameters["skip"] = LogicalType::BIGINT;
|
|
94916
94866
|
}
|
|
94917
94867
|
|
|
94918
|
-
|
|
94868
|
+
double CSVReaderProgress(ClientContext &context, const FunctionData *bind_data_p) {
|
|
94919
94869
|
auto &bind_data = (ReadCSVData &)*bind_data_p;
|
|
94920
94870
|
if (bind_data.file_size == 0) {
|
|
94921
94871
|
return 100;
|
|
94922
94872
|
}
|
|
94923
|
-
auto percentage = bind_data.bytes_read * 100 / bind_data.file_size;
|
|
94873
|
+
auto percentage = (bind_data.bytes_read * 100.0) / bind_data.file_size;
|
|
94924
94874
|
return percentage;
|
|
94925
94875
|
}
|
|
94926
94876
|
|
|
@@ -98134,14 +98084,14 @@ bool TableScanParallelStateNext(ClientContext &context, const FunctionData *bind
|
|
|
98134
98084
|
state.column_ids);
|
|
98135
98085
|
}
|
|
98136
98086
|
|
|
98137
|
-
|
|
98087
|
+
double TableScanProgress(ClientContext &context, const FunctionData *bind_data_p) {
|
|
98138
98088
|
auto &bind_data = (TableScanBindData &)*bind_data_p;
|
|
98139
98089
|
idx_t total_rows = bind_data.table->storage->GetTotalRows();
|
|
98140
98090
|
if (total_rows == 0 || total_rows < STANDARD_VECTOR_SIZE) {
|
|
98141
98091
|
//! Table is either empty or smaller than a vector size, so it is finished
|
|
98142
98092
|
return 100;
|
|
98143
98093
|
}
|
|
98144
|
-
auto percentage = (bind_data.chunk_count * STANDARD_VECTOR_SIZE * 100) / total_rows;
|
|
98094
|
+
auto percentage = double(bind_data.chunk_count * STANDARD_VECTOR_SIZE * 100.0) / total_rows;
|
|
98145
98095
|
if (percentage > 100) {
|
|
98146
98096
|
//! In case the last chunk has less elements than STANDARD_VECTOR_SIZE, if our percentage is over 100
|
|
98147
98097
|
//! It means we finished this table.
|
|
@@ -100877,28 +100827,27 @@ private:
|
|
|
100877
100827
|
|
|
100878
100828
|
namespace duckdb {
|
|
100879
100829
|
|
|
100880
|
-
|
|
100881
|
-
|
|
100882
|
-
|
|
100883
|
-
|
|
100884
|
-
|
|
100885
|
-
|
|
100886
|
-
|
|
100887
|
-
|
|
100888
|
-
|
|
100889
|
-
|
|
100830
|
+
struct ActiveQueryContext {
|
|
100831
|
+
//! The query that is currently being executed
|
|
100832
|
+
string query;
|
|
100833
|
+
//! The currently open result
|
|
100834
|
+
BaseQueryResult *open_result = nullptr;
|
|
100835
|
+
//! Prepared statement data
|
|
100836
|
+
shared_ptr<PreparedStatementData> prepared;
|
|
100837
|
+
//! The query executor
|
|
100838
|
+
unique_ptr<Executor> executor;
|
|
100839
|
+
//! The progress bar
|
|
100840
|
+
unique_ptr<ProgressBar> progress_bar;
|
|
100890
100841
|
};
|
|
100891
100842
|
|
|
100892
100843
|
ClientContext::ClientContext(shared_ptr<DatabaseInstance> database)
|
|
100893
|
-
: profiler(make_unique<QueryProfiler>()), query_profiler_history(make_unique<QueryProfilerHistory>()),
|
|
100894
|
-
db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false),
|
|
100844
|
+
: profiler(make_unique<QueryProfiler>(*this)), query_profiler_history(make_unique<QueryProfilerHistory>()),
|
|
100845
|
+
db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false),
|
|
100895
100846
|
temporary_objects(make_unique<SchemaCatalogEntry>(&db->GetCatalog(), TEMP_SCHEMA, true)),
|
|
100896
100847
|
catalog_search_path(make_unique<CatalogSearchPath>(*this)),
|
|
100897
|
-
file_opener(make_unique<ClientContextFileOpener>(*this))
|
|
100848
|
+
file_opener(make_unique<ClientContextFileOpener>(*this)) {
|
|
100898
100849
|
std::random_device rd;
|
|
100899
100850
|
random_engine.seed(rd());
|
|
100900
|
-
|
|
100901
|
-
progress_bar = make_unique<ProgressBar>(&executor, config.wait_time);
|
|
100902
100851
|
}
|
|
100903
100852
|
|
|
100904
100853
|
ClientContext::~ClientContext() {
|
|
@@ -100925,87 +100874,162 @@ void ClientContext::Destroy() {
|
|
|
100925
100874
|
CleanupInternal(*lock);
|
|
100926
100875
|
}
|
|
100927
100876
|
|
|
100928
|
-
|
|
100929
|
-
|
|
100930
|
-
|
|
100877
|
+
unique_ptr<DataChunk> ClientContext::Fetch(ClientContextLock &lock, StreamQueryResult &result) {
|
|
100878
|
+
D_ASSERT(IsActiveResult(lock, &result));
|
|
100879
|
+
D_ASSERT(active_query->executor);
|
|
100880
|
+
return FetchInternal(lock, *active_query->executor, result);
|
|
100931
100881
|
}
|
|
100932
100882
|
|
|
100933
|
-
unique_ptr<DataChunk> ClientContext::
|
|
100934
|
-
|
|
100935
|
-
|
|
100936
|
-
throw InternalException("Fetch was called, but there is no open result (or the result was previously closed)");
|
|
100937
|
-
}
|
|
100883
|
+
unique_ptr<DataChunk> ClientContext::FetchInternal(ClientContextLock &lock, Executor &executor,
|
|
100884
|
+
BaseQueryResult &result) {
|
|
100885
|
+
bool invalidate_query = true;
|
|
100938
100886
|
try {
|
|
100939
100887
|
// fetch the chunk and return it
|
|
100940
|
-
auto chunk =
|
|
100888
|
+
auto chunk = executor.FetchChunk();
|
|
100889
|
+
if (!chunk || chunk->size() == 0) {
|
|
100890
|
+
CleanupInternal(lock, &result);
|
|
100891
|
+
}
|
|
100941
100892
|
return chunk;
|
|
100893
|
+
} catch (StandardException &ex) {
|
|
100894
|
+
// standard exceptions do not invalidate the current transaction
|
|
100895
|
+
result.error = ex.what();
|
|
100896
|
+
invalidate_query = false;
|
|
100942
100897
|
} catch (std::exception &ex) {
|
|
100943
|
-
|
|
100898
|
+
result.error = ex.what();
|
|
100944
100899
|
} catch (...) { // LCOV_EXCL_START
|
|
100945
|
-
|
|
100900
|
+
result.error = "Unhandled exception in FetchInternal";
|
|
100946
100901
|
} // LCOV_EXCL_STOP
|
|
100947
|
-
|
|
100948
|
-
CleanupInternal(
|
|
100902
|
+
result.success = false;
|
|
100903
|
+
CleanupInternal(lock, &result, invalidate_query);
|
|
100949
100904
|
return nullptr;
|
|
100950
100905
|
}
|
|
100951
100906
|
|
|
100952
|
-
|
|
100907
|
+
void ClientContext::BeginTransactionInternal(ClientContextLock &lock, bool requires_valid_transaction) {
|
|
100908
|
+
// check if we are on AutoCommit. In this case we should start a transaction
|
|
100909
|
+
D_ASSERT(!active_query);
|
|
100910
|
+
if (requires_valid_transaction && transaction.HasActiveTransaction() &&
|
|
100911
|
+
transaction.ActiveTransaction().IsInvalidated()) {
|
|
100912
|
+
throw Exception("Failed: transaction has been invalidated!");
|
|
100913
|
+
}
|
|
100914
|
+
active_query = make_unique<ActiveQueryContext>();
|
|
100915
|
+
if (transaction.IsAutoCommit()) {
|
|
100916
|
+
transaction.BeginTransaction();
|
|
100917
|
+
}
|
|
100918
|
+
}
|
|
100919
|
+
|
|
100920
|
+
void ClientContext::BeginQueryInternal(ClientContextLock &lock, const string &query) {
|
|
100921
|
+
BeginTransactionInternal(lock, false);
|
|
100922
|
+
LogQueryInternal(lock, query);
|
|
100923
|
+
active_query->query = query;
|
|
100924
|
+
query_progress = -1;
|
|
100925
|
+
ActiveTransaction().active_query = db->GetTransactionManager().GetQueryNumber();
|
|
100926
|
+
}
|
|
100927
|
+
|
|
100928
|
+
string ClientContext::EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction) {
|
|
100953
100929
|
profiler->EndQuery();
|
|
100954
|
-
executor.Reset();
|
|
100955
100930
|
|
|
100931
|
+
D_ASSERT(active_query.get());
|
|
100956
100932
|
string error;
|
|
100957
|
-
|
|
100958
|
-
|
|
100959
|
-
|
|
100960
|
-
|
|
100961
|
-
|
|
100962
|
-
|
|
100963
|
-
|
|
100964
|
-
|
|
100965
|
-
|
|
100966
|
-
|
|
100967
|
-
|
|
100968
|
-
|
|
100969
|
-
|
|
100933
|
+
try {
|
|
100934
|
+
if (transaction.HasActiveTransaction()) {
|
|
100935
|
+
// Move the query profiler into the history
|
|
100936
|
+
auto &prev_profilers = query_profiler_history->GetPrevProfilers();
|
|
100937
|
+
prev_profilers.emplace_back(transaction.ActiveTransaction().active_query, move(profiler));
|
|
100938
|
+
// Reinitialize the query profiler
|
|
100939
|
+
profiler = make_unique<QueryProfiler>(*this);
|
|
100940
|
+
// Propagate settings of the saved query into the new profiler.
|
|
100941
|
+
profiler->Propagate(*prev_profilers.back().second);
|
|
100942
|
+
if (prev_profilers.size() >= query_profiler_history->GetPrevProfilersSize()) {
|
|
100943
|
+
prev_profilers.pop_front();
|
|
100944
|
+
}
|
|
100945
|
+
|
|
100946
|
+
ActiveTransaction().active_query = MAXIMUM_QUERY_ID;
|
|
100970
100947
|
if (transaction.IsAutoCommit()) {
|
|
100971
100948
|
if (success) {
|
|
100972
|
-
// query was successful: commit
|
|
100973
100949
|
transaction.Commit();
|
|
100974
100950
|
} else {
|
|
100975
|
-
// query was unsuccessful: rollback
|
|
100976
100951
|
transaction.Rollback();
|
|
100977
100952
|
}
|
|
100953
|
+
} else if (invalidate_transaction) {
|
|
100954
|
+
D_ASSERT(!success);
|
|
100955
|
+
ActiveTransaction().Invalidate();
|
|
100978
100956
|
}
|
|
100979
|
-
}
|
|
100980
|
-
|
|
100981
|
-
|
|
100982
|
-
|
|
100983
|
-
|
|
100984
|
-
}
|
|
100957
|
+
}
|
|
100958
|
+
} catch (std::exception &ex) {
|
|
100959
|
+
error = ex.what();
|
|
100960
|
+
} catch (...) { // LCOV_EXCL_START
|
|
100961
|
+
error = "Unhandled exception!";
|
|
100962
|
+
} // LCOV_EXCL_STOP
|
|
100963
|
+
active_query.reset();
|
|
100964
|
+
query_progress = -1;
|
|
100985
100965
|
return error;
|
|
100986
100966
|
}
|
|
100987
100967
|
|
|
100988
|
-
void ClientContext::CleanupInternal(ClientContextLock &lock) {
|
|
100989
|
-
if (!
|
|
100990
|
-
// no
|
|
100968
|
+
void ClientContext::CleanupInternal(ClientContextLock &lock, BaseQueryResult *result, bool invalidate_transaction) {
|
|
100969
|
+
if (!active_query) {
|
|
100970
|
+
// no query currently active
|
|
100991
100971
|
return;
|
|
100992
100972
|
}
|
|
100973
|
+
if (active_query->executor) {
|
|
100974
|
+
active_query->executor->CancelTasks();
|
|
100975
|
+
}
|
|
100976
|
+
active_query->progress_bar.reset();
|
|
100993
100977
|
|
|
100994
|
-
auto error =
|
|
100995
|
-
if (
|
|
100978
|
+
auto error = EndQueryInternal(lock, result ? result->success : false, invalidate_transaction);
|
|
100979
|
+
if (result && result->success) {
|
|
100996
100980
|
// if an error occurred while committing report it in the result
|
|
100997
|
-
|
|
100998
|
-
|
|
100981
|
+
result->error = error;
|
|
100982
|
+
result->success = error.empty();
|
|
100999
100983
|
}
|
|
100984
|
+
D_ASSERT(!active_query);
|
|
100985
|
+
}
|
|
101000
100986
|
|
|
101001
|
-
|
|
101002
|
-
|
|
100987
|
+
Executor &ClientContext::GetExecutor() {
|
|
100988
|
+
D_ASSERT(active_query);
|
|
100989
|
+
D_ASSERT(active_query->executor);
|
|
100990
|
+
return *active_query->executor;
|
|
100991
|
+
}
|
|
101003
100992
|
|
|
101004
|
-
|
|
100993
|
+
const string &ClientContext::GetCurrentQuery() {
|
|
100994
|
+
D_ASSERT(active_query);
|
|
100995
|
+
return active_query->query;
|
|
101005
100996
|
}
|
|
101006
100997
|
|
|
101007
|
-
unique_ptr<
|
|
101008
|
-
|
|
100998
|
+
unique_ptr<QueryResult> ClientContext::FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending,
|
|
100999
|
+
bool allow_stream_result) {
|
|
101000
|
+
D_ASSERT(active_query);
|
|
101001
|
+
D_ASSERT(active_query->open_result == &pending);
|
|
101002
|
+
D_ASSERT(active_query->prepared);
|
|
101003
|
+
auto &prepared = *active_query->prepared;
|
|
101004
|
+
bool create_stream_result = prepared.allow_stream_result && allow_stream_result;
|
|
101005
|
+
if (create_stream_result) {
|
|
101006
|
+
active_query->progress_bar.reset();
|
|
101007
|
+
query_progress = -1;
|
|
101008
|
+
|
|
101009
|
+
// successfully compiled SELECT clause and it is the last statement
|
|
101010
|
+
// return a StreamQueryResult so the client can call Fetch() on it and stream the result
|
|
101011
|
+
auto stream_result =
|
|
101012
|
+
make_unique<StreamQueryResult>(pending.statement_type, shared_from_this(), pending.types, pending.names);
|
|
101013
|
+
active_query->open_result = stream_result.get();
|
|
101014
|
+
return move(stream_result);
|
|
101015
|
+
}
|
|
101016
|
+
// create a materialized result by continuously fetching
|
|
101017
|
+
auto result = make_unique<MaterializedQueryResult>(pending.statement_type, pending.types, pending.names);
|
|
101018
|
+
while (true) {
|
|
101019
|
+
auto chunk = FetchInternal(lock, GetExecutor(), *result);
|
|
101020
|
+
if (!chunk || chunk->size() == 0) {
|
|
101021
|
+
break;
|
|
101022
|
+
}
|
|
101023
|
+
#ifdef DEBUG
|
|
101024
|
+
for (idx_t i = 0; i < chunk->ColumnCount(); i++) {
|
|
101025
|
+
if (pending.types[i].id() == LogicalTypeId::VARCHAR) {
|
|
101026
|
+
chunk->data[i].UTFVerify(chunk->size());
|
|
101027
|
+
}
|
|
101028
|
+
}
|
|
101029
|
+
#endif
|
|
101030
|
+
result->collection.Append(*chunk);
|
|
101031
|
+
}
|
|
101032
|
+
return move(result);
|
|
101009
101033
|
}
|
|
101010
101034
|
|
|
101011
101035
|
shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientContextLock &lock, const string &query,
|
|
@@ -101013,11 +101037,12 @@ shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientC
|
|
|
101013
101037
|
StatementType statement_type = statement->type;
|
|
101014
101038
|
auto result = make_shared<PreparedStatementData>(statement_type);
|
|
101015
101039
|
|
|
101016
|
-
profiler
|
|
101040
|
+
auto &profiler = QueryProfiler::Get(*this);
|
|
101041
|
+
profiler.StartPhase("planner");
|
|
101017
101042
|
Planner planner(*this);
|
|
101018
101043
|
planner.CreatePlan(move(statement));
|
|
101019
101044
|
D_ASSERT(planner.plan);
|
|
101020
|
-
profiler
|
|
101045
|
+
profiler.EndPhase();
|
|
101021
101046
|
|
|
101022
101047
|
auto plan = move(planner.plan);
|
|
101023
101048
|
#ifdef DEBUG
|
|
@@ -101033,22 +101058,22 @@ shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientC
|
|
|
101033
101058
|
result->catalog_version = Transaction::GetTransaction(*this).catalog_version;
|
|
101034
101059
|
|
|
101035
101060
|
if (config.enable_optimizer) {
|
|
101036
|
-
profiler
|
|
101061
|
+
profiler.StartPhase("optimizer");
|
|
101037
101062
|
Optimizer optimizer(*planner.binder, *this);
|
|
101038
101063
|
plan = optimizer.Optimize(move(plan));
|
|
101039
101064
|
D_ASSERT(plan);
|
|
101040
|
-
profiler
|
|
101065
|
+
profiler.EndPhase();
|
|
101041
101066
|
|
|
101042
101067
|
#ifdef DEBUG
|
|
101043
101068
|
plan->Verify();
|
|
101044
101069
|
#endif
|
|
101045
101070
|
}
|
|
101046
101071
|
|
|
101047
|
-
profiler
|
|
101072
|
+
profiler.StartPhase("physical_planner");
|
|
101048
101073
|
// now convert logical query plan into a physical query plan
|
|
101049
101074
|
PhysicalPlanGenerator physical_planner(*this);
|
|
101050
101075
|
auto physical_plan = physical_planner.CreatePlan(move(plan));
|
|
101051
|
-
profiler
|
|
101076
|
+
profiler.EndPhase();
|
|
101052
101077
|
|
|
101053
101078
|
#ifdef DEBUG
|
|
101054
101079
|
D_ASSERT(!physical_plan->ToString().empty());
|
|
@@ -101057,14 +101082,14 @@ shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientC
|
|
|
101057
101082
|
return result;
|
|
101058
101083
|
}
|
|
101059
101084
|
|
|
101060
|
-
|
|
101061
|
-
|
|
101062
|
-
return progress_bar->GetCurrentPercentage();
|
|
101085
|
+
double ClientContext::GetProgress() {
|
|
101086
|
+
return query_progress.load();
|
|
101063
101087
|
}
|
|
101064
101088
|
|
|
101065
|
-
unique_ptr<
|
|
101066
|
-
|
|
101067
|
-
|
|
101089
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingPreparedStatement(ClientContextLock &lock,
|
|
101090
|
+
shared_ptr<PreparedStatementData> statement_p,
|
|
101091
|
+
vector<Value> bound_values) {
|
|
101092
|
+
D_ASSERT(active_query);
|
|
101068
101093
|
auto &statement = *statement_p;
|
|
101069
101094
|
if (ActiveTransaction().IsInvalidated() && statement.requires_valid_transaction) {
|
|
101070
101095
|
throw Exception("Current transaction is aborted (please ROLLBACK)");
|
|
@@ -101078,47 +101103,42 @@ unique_ptr<QueryResult> ClientContext::ExecutePreparedStatement(ClientContextLoc
|
|
|
101078
101103
|
// bind the bound values before execution
|
|
101079
101104
|
statement.Bind(move(bound_values));
|
|
101080
101105
|
|
|
101081
|
-
|
|
101106
|
+
active_query->executor = make_unique<Executor>(*this);
|
|
101107
|
+
auto &executor = *active_query->executor;
|
|
101082
101108
|
if (config.enable_progress_bar) {
|
|
101083
|
-
progress_bar
|
|
101084
|
-
progress_bar->Start();
|
|
101109
|
+
active_query->progress_bar = make_unique<ProgressBar>(executor, config.wait_time);
|
|
101110
|
+
active_query->progress_bar->Start();
|
|
101111
|
+
query_progress = 0;
|
|
101085
101112
|
}
|
|
101086
|
-
// store the physical plan in the context for calls to Fetch()
|
|
101087
101113
|
executor.Initialize(statement.plan.get());
|
|
101088
|
-
|
|
101089
101114
|
auto types = executor.GetTypes();
|
|
101090
|
-
|
|
101091
101115
|
D_ASSERT(types == statement.types);
|
|
101116
|
+
D_ASSERT(!active_query->open_result);
|
|
101092
101117
|
|
|
101093
|
-
|
|
101094
|
-
|
|
101095
|
-
|
|
101096
|
-
|
|
101097
|
-
|
|
101098
|
-
|
|
101099
|
-
|
|
101100
|
-
|
|
101101
|
-
|
|
101102
|
-
|
|
101103
|
-
|
|
101104
|
-
|
|
101105
|
-
|
|
101106
|
-
|
|
101107
|
-
break;
|
|
101108
|
-
}
|
|
101109
|
-
#ifdef DEBUG
|
|
101110
|
-
for (idx_t i = 0; i < chunk->ColumnCount(); i++) {
|
|
101111
|
-
if (statement.types[i].id() == LogicalTypeId::VARCHAR) {
|
|
101112
|
-
chunk->data[i].UTFVerify(chunk->size());
|
|
101113
|
-
}
|
|
101118
|
+
auto pending_result = make_unique<PendingQueryResult>(shared_from_this(), *statement_p, move(types));
|
|
101119
|
+
active_query->prepared = move(statement_p);
|
|
101120
|
+
active_query->open_result = pending_result.get();
|
|
101121
|
+
return pending_result;
|
|
101122
|
+
}
|
|
101123
|
+
|
|
101124
|
+
PendingExecutionResult ClientContext::ExecuteTaskInternal(ClientContextLock &lock, PendingQueryResult &result) {
|
|
101125
|
+
D_ASSERT(active_query);
|
|
101126
|
+
D_ASSERT(active_query->open_result == &result);
|
|
101127
|
+
try {
|
|
101128
|
+
auto result = active_query->executor->ExecuteTask();
|
|
101129
|
+
if (active_query->progress_bar) {
|
|
101130
|
+
active_query->progress_bar->Update(result == PendingExecutionResult::RESULT_READY);
|
|
101131
|
+
query_progress = active_query->progress_bar->GetCurrentPercentage();
|
|
101114
101132
|
}
|
|
101115
|
-
|
|
101116
|
-
|
|
101117
|
-
|
|
101118
|
-
|
|
101119
|
-
|
|
101120
|
-
}
|
|
101121
|
-
|
|
101133
|
+
return result;
|
|
101134
|
+
} catch (std::exception &ex) {
|
|
101135
|
+
result.error = ex.what();
|
|
101136
|
+
} catch (...) { // LCOV_EXCL_START
|
|
101137
|
+
result.error = "Unhandled exception in ExecuteTaskInternal";
|
|
101138
|
+
} // LCOV_EXCL_STOP
|
|
101139
|
+
EndQueryInternal(lock, false, true);
|
|
101140
|
+
result.success = false;
|
|
101141
|
+
return PendingExecutionResult::EXECUTION_ERROR;
|
|
101122
101142
|
}
|
|
101123
101143
|
|
|
101124
101144
|
void ClientContext::InitialCleanup(ClientContextLock &lock) {
|
|
@@ -101221,27 +101241,58 @@ unique_ptr<PreparedStatement> ClientContext::Prepare(const string &query) {
|
|
|
101221
101241
|
}
|
|
101222
101242
|
}
|
|
101223
101243
|
|
|
101244
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQueryPreparedInternal(ClientContextLock &lock, const string &query,
|
|
101245
|
+
shared_ptr<PreparedStatementData> &prepared,
|
|
101246
|
+
vector<Value> &values) {
|
|
101247
|
+
try {
|
|
101248
|
+
InitialCleanup(lock);
|
|
101249
|
+
} catch (std::exception &ex) {
|
|
101250
|
+
return make_unique<PendingQueryResult>(ex.what());
|
|
101251
|
+
}
|
|
101252
|
+
return PendingStatementOrPreparedStatementInternal(lock, query, nullptr, prepared, &values);
|
|
101253
|
+
}
|
|
101254
|
+
|
|
101255
|
+
unique_ptr<PendingQueryResult>
|
|
101256
|
+
ClientContext::PendingQuery(const string &query, shared_ptr<PreparedStatementData> &prepared, vector<Value> &values) {
|
|
101257
|
+
auto lock = LockContext();
|
|
101258
|
+
return PendingQueryPreparedInternal(*lock, query, prepared, values);
|
|
101259
|
+
}
|
|
101260
|
+
|
|
101224
101261
|
unique_ptr<QueryResult> ClientContext::Execute(const string &query, shared_ptr<PreparedStatementData> &prepared,
|
|
101225
101262
|
vector<Value> &values, bool allow_stream_result) {
|
|
101226
101263
|
auto lock = LockContext();
|
|
101227
|
-
|
|
101228
|
-
|
|
101229
|
-
|
|
101230
|
-
return make_unique<MaterializedQueryResult>(ex.what());
|
|
101264
|
+
auto pending = PendingQueryPreparedInternal(*lock, query, prepared, values);
|
|
101265
|
+
if (!pending->success) {
|
|
101266
|
+
return make_unique<MaterializedQueryResult>(pending->error);
|
|
101231
101267
|
}
|
|
101232
|
-
|
|
101233
|
-
return RunStatementOrPreparedStatement(*lock, query, nullptr, prepared, &values, allow_stream_result);
|
|
101268
|
+
return pending->ExecuteInternal(*lock, allow_stream_result);
|
|
101234
101269
|
}
|
|
101235
101270
|
|
|
101236
|
-
unique_ptr<
|
|
101237
|
-
|
|
101238
|
-
bool allow_stream_result) {
|
|
101271
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingStatementInternal(ClientContextLock &lock, const string &query,
|
|
101272
|
+
unique_ptr<SQLStatement> statement) {
|
|
101239
101273
|
// prepare the query for execution
|
|
101240
101274
|
auto prepared = CreatePreparedStatement(lock, query, move(statement));
|
|
101241
101275
|
// by default, no values are bound
|
|
101242
101276
|
vector<Value> bound_values;
|
|
101243
101277
|
// execute the prepared statement
|
|
101244
|
-
return
|
|
101278
|
+
return PendingPreparedStatement(lock, move(prepared), move(bound_values));
|
|
101279
|
+
}
|
|
101280
|
+
|
|
101281
|
+
unique_ptr<QueryResult> ClientContext::RunStatementInternal(ClientContextLock &lock, const string &query,
|
|
101282
|
+
unique_ptr<SQLStatement> statement,
|
|
101283
|
+
bool allow_stream_result, bool verify) {
|
|
101284
|
+
auto pending = PendingQueryInternal(lock, move(statement), verify);
|
|
101285
|
+
if (!pending->success) {
|
|
101286
|
+
return make_unique<MaterializedQueryResult>(move(pending->error));
|
|
101287
|
+
}
|
|
101288
|
+
return ExecutePendingQueryInternal(lock, *pending, allow_stream_result);
|
|
101289
|
+
}
|
|
101290
|
+
|
|
101291
|
+
bool ClientContext::IsActiveResult(ClientContextLock &lock, BaseQueryResult *result) {
|
|
101292
|
+
if (!active_query) {
|
|
101293
|
+
return false;
|
|
101294
|
+
}
|
|
101295
|
+
return active_query->open_result == result;
|
|
101245
101296
|
}
|
|
101246
101297
|
|
|
101247
101298
|
static bool IsExplainAnalyze(SQLStatement *statement) {
|
|
@@ -101255,19 +101306,10 @@ static bool IsExplainAnalyze(SQLStatement *statement) {
|
|
|
101255
101306
|
return explain.explain_type == ExplainType::EXPLAIN_ANALYZE;
|
|
101256
101307
|
}
|
|
101257
101308
|
|
|
101258
|
-
unique_ptr<
|
|
101259
|
-
|
|
101260
|
-
|
|
101261
|
-
vector<Value> *values,
|
|
101262
|
-
bool allow_stream_result) {
|
|
101263
|
-
this->query = query;
|
|
101264
|
-
|
|
101265
|
-
unique_ptr<QueryResult> result;
|
|
101309
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingStatementOrPreparedStatementInternal(
|
|
101310
|
+
ClientContextLock &lock, const string &query, unique_ptr<SQLStatement> statement,
|
|
101311
|
+
shared_ptr<PreparedStatementData> &prepared, vector<Value> *values) {
|
|
101266
101312
|
// check if we are on AutoCommit. In this case we should start a transaction.
|
|
101267
|
-
if (transaction.IsAutoCommit()) {
|
|
101268
|
-
transaction.BeginTransaction();
|
|
101269
|
-
}
|
|
101270
|
-
ActiveTransaction().active_query = db->GetTransactionManager().GetQueryNumber();
|
|
101271
101313
|
if (statement && config.query_verification_enabled) {
|
|
101272
101314
|
// query verification is enabled
|
|
101273
101315
|
// create a copy of the statement, and use the copy
|
|
@@ -101277,19 +101319,29 @@ unique_ptr<QueryResult> ClientContext::RunStatementOrPreparedStatement(ClientCon
|
|
|
101277
101319
|
// in case this is a select query, we verify the original statement
|
|
101278
101320
|
string error = VerifyQuery(lock, query, move(statement));
|
|
101279
101321
|
if (!error.empty()) {
|
|
101280
|
-
// query failed: abort now
|
|
101281
|
-
FinalizeQuery(lock, false);
|
|
101282
101322
|
// error in verifying query
|
|
101283
|
-
return make_unique<
|
|
101323
|
+
return make_unique<PendingQueryResult>(error);
|
|
101284
101324
|
}
|
|
101285
101325
|
}
|
|
101286
101326
|
statement = move(copied_statement);
|
|
101287
101327
|
}
|
|
101328
|
+
return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, values);
|
|
101329
|
+
}
|
|
101330
|
+
|
|
101331
|
+
unique_ptr<PendingQueryResult>
|
|
101332
|
+
ClientContext::PendingStatementOrPreparedStatement(ClientContextLock &lock, const string &query,
|
|
101333
|
+
unique_ptr<SQLStatement> statement,
|
|
101334
|
+
shared_ptr<PreparedStatementData> &prepared, vector<Value> *values) {
|
|
101335
|
+
unique_ptr<PendingQueryResult> result;
|
|
101336
|
+
|
|
101337
|
+
BeginQueryInternal(lock, query);
|
|
101288
101338
|
// start the profiler
|
|
101289
|
-
profiler
|
|
101339
|
+
auto &profiler = QueryProfiler::Get(*this);
|
|
101340
|
+
profiler.StartQuery(query, IsExplainAnalyze(statement ? statement.get() : prepared->unbound_statement.get()));
|
|
101341
|
+
bool invalidate_query = true;
|
|
101290
101342
|
try {
|
|
101291
101343
|
if (statement) {
|
|
101292
|
-
result =
|
|
101344
|
+
result = PendingStatementInternal(lock, query, move(statement));
|
|
101293
101345
|
} else {
|
|
101294
101346
|
auto &catalog = Catalog::GetCatalog(*this);
|
|
101295
101347
|
if (prepared->unbound_statement && catalog.GetCatalogVersion() != prepared->catalog_version) {
|
|
@@ -101302,68 +101354,22 @@ unique_ptr<QueryResult> ClientContext::RunStatementOrPreparedStatement(ClientCon
|
|
|
101302
101354
|
new_prepared->unbound_statement = move(prepared->unbound_statement);
|
|
101303
101355
|
prepared = move(new_prepared);
|
|
101304
101356
|
}
|
|
101305
|
-
result =
|
|
101357
|
+
result = PendingPreparedStatement(lock, prepared, *values);
|
|
101306
101358
|
}
|
|
101307
101359
|
} catch (StandardException &ex) {
|
|
101308
101360
|
// standard exceptions do not invalidate the current transaction
|
|
101309
|
-
result = make_unique<
|
|
101361
|
+
result = make_unique<PendingQueryResult>(ex.what());
|
|
101362
|
+
invalidate_query = false;
|
|
101310
101363
|
} catch (std::exception &ex) {
|
|
101311
101364
|
// other types of exceptions do invalidate the current transaction
|
|
101312
|
-
|
|
101313
|
-
ActiveTransaction().Invalidate();
|
|
101314
|
-
}
|
|
101315
|
-
result = make_unique<MaterializedQueryResult>(ex.what());
|
|
101365
|
+
result = make_unique<PendingQueryResult>(ex.what());
|
|
101316
101366
|
}
|
|
101317
101367
|
if (!result->success) {
|
|
101318
|
-
// initial failures should always be reported as MaterializedResult
|
|
101319
|
-
D_ASSERT(result->type != QueryResultType::STREAM_RESULT);
|
|
101320
101368
|
// query failed: abort now
|
|
101321
|
-
|
|
101369
|
+
EndQueryInternal(lock, false, invalidate_query);
|
|
101322
101370
|
return result;
|
|
101323
101371
|
}
|
|
101324
|
-
|
|
101325
|
-
if (result->type == QueryResultType::STREAM_RESULT) {
|
|
101326
|
-
// store as currently open result if it is a stream result
|
|
101327
|
-
this->open_result = (StreamQueryResult *)result.get();
|
|
101328
|
-
} else {
|
|
101329
|
-
// finalize the query if it is not a stream result
|
|
101330
|
-
string error = FinalizeQuery(lock, true);
|
|
101331
|
-
if (!error.empty()) {
|
|
101332
|
-
// failure in committing transaction
|
|
101333
|
-
return make_unique<MaterializedQueryResult>(error);
|
|
101334
|
-
}
|
|
101335
|
-
}
|
|
101336
|
-
return result;
|
|
101337
|
-
}
|
|
101338
|
-
|
|
101339
|
-
unique_ptr<QueryResult> ClientContext::RunStatement(ClientContextLock &lock, const string &query,
|
|
101340
|
-
unique_ptr<SQLStatement> statement, bool allow_stream_result) {
|
|
101341
|
-
shared_ptr<PreparedStatementData> prepared;
|
|
101342
|
-
return RunStatementOrPreparedStatement(lock, query, move(statement), prepared, nullptr, allow_stream_result);
|
|
101343
|
-
}
|
|
101344
|
-
|
|
101345
|
-
unique_ptr<QueryResult> ClientContext::RunStatements(ClientContextLock &lock, const string &query,
|
|
101346
|
-
vector<unique_ptr<SQLStatement>> &statements,
|
|
101347
|
-
bool allow_stream_result) {
|
|
101348
|
-
// now we have a list of statements
|
|
101349
|
-
// iterate over them and execute them one by one
|
|
101350
|
-
unique_ptr<QueryResult> result;
|
|
101351
|
-
QueryResult *last_result = nullptr;
|
|
101352
|
-
for (idx_t i = 0; i < statements.size(); i++) {
|
|
101353
|
-
auto &statement = statements[i];
|
|
101354
|
-
bool is_last_statement = i + 1 == statements.size();
|
|
101355
|
-
auto current_result = RunStatement(lock, query, move(statement), allow_stream_result && is_last_statement);
|
|
101356
|
-
// now append the result to the list of results
|
|
101357
|
-
if (!last_result) {
|
|
101358
|
-
// first result of the query
|
|
101359
|
-
result = move(current_result);
|
|
101360
|
-
last_result = result.get();
|
|
101361
|
-
} else {
|
|
101362
|
-
// later results; attach to the result chain
|
|
101363
|
-
last_result->next = move(current_result);
|
|
101364
|
-
last_result = last_result->next.get();
|
|
101365
|
-
}
|
|
101366
|
-
}
|
|
101372
|
+
D_ASSERT(active_query->open_result == result.get());
|
|
101367
101373
|
return result;
|
|
101368
101374
|
}
|
|
101369
101375
|
|
|
@@ -101389,34 +101395,96 @@ void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) {
|
|
|
101389
101395
|
}
|
|
101390
101396
|
|
|
101391
101397
|
unique_ptr<QueryResult> ClientContext::Query(unique_ptr<SQLStatement> statement, bool allow_stream_result) {
|
|
101392
|
-
auto
|
|
101393
|
-
|
|
101394
|
-
|
|
101395
|
-
vector<unique_ptr<SQLStatement>> statements;
|
|
101396
|
-
statements.push_back(move(statement));
|
|
101397
|
-
|
|
101398
|
-
return RunStatements(*lock, query, statements, allow_stream_result);
|
|
101398
|
+
auto pending_query = PendingQuery(move(statement));
|
|
101399
|
+
return pending_query->Execute(allow_stream_result);
|
|
101399
101400
|
}
|
|
101400
101401
|
|
|
101401
101402
|
unique_ptr<QueryResult> ClientContext::Query(const string &query, bool allow_stream_result) {
|
|
101402
101403
|
auto lock = LockContext();
|
|
101403
|
-
LogQueryInternal(*lock, query);
|
|
101404
101404
|
|
|
101405
|
+
string error;
|
|
101405
101406
|
vector<unique_ptr<SQLStatement>> statements;
|
|
101407
|
+
if (!ParseStatements(*lock, query, statements, error)) {
|
|
101408
|
+
return make_unique<MaterializedQueryResult>(move(error));
|
|
101409
|
+
}
|
|
101410
|
+
if (statements.empty()) {
|
|
101411
|
+
// no statements, return empty successful result
|
|
101412
|
+
return make_unique<MaterializedQueryResult>(StatementType::INVALID_STATEMENT);
|
|
101413
|
+
}
|
|
101414
|
+
|
|
101415
|
+
unique_ptr<QueryResult> result;
|
|
101416
|
+
QueryResult *last_result = nullptr;
|
|
101417
|
+
for (idx_t i = 0; i < statements.size(); i++) {
|
|
101418
|
+
auto &statement = statements[i];
|
|
101419
|
+
bool is_last_statement = i + 1 == statements.size();
|
|
101420
|
+
bool stream_result = allow_stream_result && is_last_statement;
|
|
101421
|
+
auto pending_query = PendingQueryInternal(*lock, move(statement));
|
|
101422
|
+
unique_ptr<QueryResult> current_result;
|
|
101423
|
+
if (!pending_query->success) {
|
|
101424
|
+
current_result = make_unique<MaterializedQueryResult>(pending_query->error);
|
|
101425
|
+
} else {
|
|
101426
|
+
current_result = ExecutePendingQueryInternal(*lock, *pending_query, stream_result);
|
|
101427
|
+
}
|
|
101428
|
+
// now append the result to the list of results
|
|
101429
|
+
if (!last_result) {
|
|
101430
|
+
// first result of the query
|
|
101431
|
+
result = move(current_result);
|
|
101432
|
+
last_result = result.get();
|
|
101433
|
+
} else {
|
|
101434
|
+
// later results; attach to the result chain
|
|
101435
|
+
last_result->next = move(current_result);
|
|
101436
|
+
last_result = last_result->next.get();
|
|
101437
|
+
}
|
|
101438
|
+
}
|
|
101439
|
+
return result;
|
|
101440
|
+
}
|
|
101441
|
+
|
|
101442
|
+
bool ClientContext::ParseStatements(ClientContextLock &lock, const string &query,
|
|
101443
|
+
vector<unique_ptr<SQLStatement>> &result, string &error) {
|
|
101406
101444
|
try {
|
|
101407
|
-
InitialCleanup(
|
|
101445
|
+
InitialCleanup(lock);
|
|
101408
101446
|
// parse the query and transform it into a set of statements
|
|
101409
|
-
|
|
101447
|
+
result = ParseStatementsInternal(lock, query);
|
|
101448
|
+
return true;
|
|
101410
101449
|
} catch (std::exception &ex) {
|
|
101411
|
-
|
|
101450
|
+
error = ex.what();
|
|
101451
|
+
return false;
|
|
101412
101452
|
}
|
|
101453
|
+
}
|
|
101413
101454
|
|
|
101414
|
-
|
|
101415
|
-
|
|
101416
|
-
|
|
101455
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQuery(const string &query) {
|
|
101456
|
+
auto lock = LockContext();
|
|
101457
|
+
|
|
101458
|
+
string error;
|
|
101459
|
+
vector<unique_ptr<SQLStatement>> statements;
|
|
101460
|
+
if (!ParseStatements(*lock, query, statements, error)) {
|
|
101461
|
+
return make_unique<PendingQueryResult>(move(error));
|
|
101462
|
+
}
|
|
101463
|
+
if (statements.size() != 1) {
|
|
101464
|
+
return make_unique<PendingQueryResult>("PendingQuery can only take a single statement");
|
|
101465
|
+
}
|
|
101466
|
+
return PendingQueryInternal(*lock, move(statements[0]));
|
|
101467
|
+
}
|
|
101468
|
+
|
|
101469
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQuery(unique_ptr<SQLStatement> statement) {
|
|
101470
|
+
auto lock = LockContext();
|
|
101471
|
+
return PendingQueryInternal(*lock, move(statement));
|
|
101472
|
+
}
|
|
101473
|
+
|
|
101474
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQueryInternal(ClientContextLock &lock,
|
|
101475
|
+
unique_ptr<SQLStatement> statement, bool verify) {
|
|
101476
|
+
auto query = statement->query;
|
|
101477
|
+
shared_ptr<PreparedStatementData> prepared;
|
|
101478
|
+
if (verify) {
|
|
101479
|
+
return PendingStatementOrPreparedStatementInternal(lock, query, move(statement), prepared, nullptr);
|
|
101480
|
+
} else {
|
|
101481
|
+
return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, nullptr);
|
|
101417
101482
|
}
|
|
101483
|
+
}
|
|
101418
101484
|
|
|
101419
|
-
|
|
101485
|
+
unique_ptr<QueryResult> ClientContext::ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query,
|
|
101486
|
+
bool allow_stream_result) {
|
|
101487
|
+
return query.ExecuteInternal(lock, allow_stream_result);
|
|
101420
101488
|
}
|
|
101421
101489
|
|
|
101422
101490
|
void ClientContext::Interrupt() {
|
|
@@ -101425,12 +101493,14 @@ void ClientContext::Interrupt() {
|
|
|
101425
101493
|
|
|
101426
101494
|
void ClientContext::EnableProfiling() {
|
|
101427
101495
|
auto lock = LockContext();
|
|
101428
|
-
|
|
101496
|
+
auto &config = ClientConfig::GetConfig(*this);
|
|
101497
|
+
config.enable_profiler = true;
|
|
101429
101498
|
}
|
|
101430
101499
|
|
|
101431
101500
|
void ClientContext::DisableProfiling() {
|
|
101432
101501
|
auto lock = LockContext();
|
|
101433
|
-
|
|
101502
|
+
auto &config = ClientConfig::GetConfig(*this);
|
|
101503
|
+
config.enable_profiler = false;
|
|
101434
101504
|
}
|
|
101435
101505
|
|
|
101436
101506
|
string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query, unique_ptr<SQLStatement> statement) {
|
|
@@ -101492,9 +101562,10 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101492
101562
|
#endif
|
|
101493
101563
|
|
|
101494
101564
|
// disable profiling if it is enabled
|
|
101495
|
-
|
|
101565
|
+
auto &config = ClientConfig::GetConfig(*this);
|
|
101566
|
+
bool profiling_is_enabled = config.enable_profiler;
|
|
101496
101567
|
if (profiling_is_enabled) {
|
|
101497
|
-
|
|
101568
|
+
config.enable_profiler = false;
|
|
101498
101569
|
}
|
|
101499
101570
|
|
|
101500
101571
|
// see below
|
|
@@ -101511,7 +101582,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101511
101582
|
|
|
101512
101583
|
// execute the original statement
|
|
101513
101584
|
try {
|
|
101514
|
-
auto result = RunStatementInternal(lock, query, move(statement), false);
|
|
101585
|
+
auto result = RunStatementInternal(lock, query, move(statement), false, false);
|
|
101515
101586
|
original_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101516
101587
|
} catch (std::exception &ex) {
|
|
101517
101588
|
original_result->error = ex.what();
|
|
@@ -101524,7 +101595,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101524
101595
|
auto explain_q = "EXPLAIN " + query;
|
|
101525
101596
|
auto explain_stmt = make_unique<ExplainStatement>(move(statement_copy_for_explain));
|
|
101526
101597
|
try {
|
|
101527
|
-
RunStatementInternal(lock, explain_q, move(explain_stmt), false);
|
|
101598
|
+
RunStatementInternal(lock, explain_q, move(explain_stmt), false, false);
|
|
101528
101599
|
} catch (std::exception &ex) { // LCOV_EXCL_START
|
|
101529
101600
|
return "EXPLAIN failed but query did not (" + string(ex.what()) + ")";
|
|
101530
101601
|
} // LCOV_EXCL_STOP
|
|
@@ -101532,7 +101603,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101532
101603
|
|
|
101533
101604
|
// now execute the copied statement
|
|
101534
101605
|
try {
|
|
101535
|
-
auto result = RunStatementInternal(lock, query, move(copied_stmt), false);
|
|
101606
|
+
auto result = RunStatementInternal(lock, query, move(copied_stmt), false, false);
|
|
101536
101607
|
copied_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101537
101608
|
} catch (std::exception &ex) {
|
|
101538
101609
|
copied_result->error = ex.what();
|
|
@@ -101541,7 +101612,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101541
101612
|
}
|
|
101542
101613
|
// now execute the deserialized statement
|
|
101543
101614
|
try {
|
|
101544
|
-
auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false);
|
|
101615
|
+
auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false, false);
|
|
101545
101616
|
deserialized_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101546
101617
|
} catch (std::exception &ex) {
|
|
101547
101618
|
deserialized_result->error = ex.what();
|
|
@@ -101551,7 +101622,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101551
101622
|
// now execute the unoptimized statement
|
|
101552
101623
|
config.enable_optimizer = false;
|
|
101553
101624
|
try {
|
|
101554
|
-
auto result = RunStatementInternal(lock, query, move(unoptimized_stmt), false);
|
|
101625
|
+
auto result = RunStatementInternal(lock, query, move(unoptimized_stmt), false, false);
|
|
101555
101626
|
unoptimized_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101556
101627
|
} catch (std::exception &ex) {
|
|
101557
101628
|
unoptimized_result->error = ex.what();
|
|
@@ -101561,7 +101632,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101561
101632
|
config.enable_optimizer = true;
|
|
101562
101633
|
|
|
101563
101634
|
if (profiling_is_enabled) {
|
|
101564
|
-
|
|
101635
|
+
config.enable_profiler = true;
|
|
101565
101636
|
}
|
|
101566
101637
|
|
|
101567
101638
|
// now compare the results
|
|
@@ -101615,7 +101686,7 @@ bool ClientContext::UpdateFunctionInfoFromEntry(ScalarFunctionCatalogEntry *exis
|
|
|
101615
101686
|
void ClientContext::RegisterFunction(CreateFunctionInfo *info) {
|
|
101616
101687
|
RunFunctionInTransaction([&]() {
|
|
101617
101688
|
auto &catalog = Catalog::GetCatalog(*this);
|
|
101618
|
-
|
|
101689
|
+
auto existing_function = (ScalarFunctionCatalogEntry *)catalog.GetEntry(
|
|
101619
101690
|
*this, CatalogType::SCALAR_FUNCTION_ENTRY, info->schema, info->name, true);
|
|
101620
101691
|
if (existing_function) {
|
|
101621
101692
|
if (UpdateFunctionInfoFromEntry(existing_function, (CreateScalarFunctionInfo *)info)) {
|
|
@@ -101637,6 +101708,7 @@ void ClientContext::RunFunctionInTransactionInternal(ClientContextLock &lock, co
|
|
|
101637
101708
|
// check if we are on AutoCommit. In this case we should start a transaction
|
|
101638
101709
|
bool require_new_transaction = transaction.IsAutoCommit() && !transaction.HasActiveTransaction();
|
|
101639
101710
|
if (require_new_transaction) {
|
|
101711
|
+
D_ASSERT(!active_query);
|
|
101640
101712
|
transaction.BeginTransaction();
|
|
101641
101713
|
}
|
|
101642
101714
|
try {
|
|
@@ -101751,12 +101823,14 @@ unique_ptr<QueryResult> ClientContext::Execute(const shared_ptr<Relation> &relat
|
|
|
101751
101823
|
// verify read only statements by running a select statement
|
|
101752
101824
|
auto select = make_unique<SelectStatement>();
|
|
101753
101825
|
select->node = relation->GetQueryNode();
|
|
101754
|
-
|
|
101826
|
+
RunStatementInternal(*lock, query, move(select), false);
|
|
101755
101827
|
}
|
|
101756
101828
|
}
|
|
101757
101829
|
auto &expected_columns = relation->Columns();
|
|
101758
101830
|
auto relation_stmt = make_unique<RelationStatement>(relation);
|
|
101759
|
-
|
|
101831
|
+
|
|
101832
|
+
unique_ptr<QueryResult> result;
|
|
101833
|
+
result = RunStatementInternal(*lock, query, move(relation_stmt), false);
|
|
101760
101834
|
if (!result->success) {
|
|
101761
101835
|
return result;
|
|
101762
101836
|
}
|
|
@@ -102528,10 +102602,11 @@ Connection::Connection(DuckDB &database) : Connection(*database.instance) {
|
|
|
102528
102602
|
}
|
|
102529
102603
|
|
|
102530
102604
|
string Connection::GetProfilingInformation(ProfilerPrintFormat format) {
|
|
102605
|
+
auto &profiler = QueryProfiler::Get(*context);
|
|
102531
102606
|
if (format == ProfilerPrintFormat::JSON) {
|
|
102532
|
-
return
|
|
102607
|
+
return profiler.ToJSON();
|
|
102533
102608
|
} else {
|
|
102534
|
-
return
|
|
102609
|
+
return profiler.ToString();
|
|
102535
102610
|
}
|
|
102536
102611
|
}
|
|
102537
102612
|
|
|
@@ -102575,6 +102650,14 @@ unique_ptr<MaterializedQueryResult> Connection::Query(unique_ptr<SQLStatement> s
|
|
|
102575
102650
|
return unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
102576
102651
|
}
|
|
102577
102652
|
|
|
102653
|
+
unique_ptr<PendingQueryResult> Connection::PendingQuery(const string &query) {
|
|
102654
|
+
return context->PendingQuery(query);
|
|
102655
|
+
}
|
|
102656
|
+
|
|
102657
|
+
unique_ptr<PendingQueryResult> Connection::PendingQuery(unique_ptr<SQLStatement> statement) {
|
|
102658
|
+
return context->PendingQuery(move(statement));
|
|
102659
|
+
}
|
|
102660
|
+
|
|
102578
102661
|
unique_ptr<PreparedStatement> Connection::Prepare(const string &query) {
|
|
102579
102662
|
return context->Prepare(query);
|
|
102580
102663
|
}
|
|
@@ -110883,6 +110966,75 @@ unique_ptr<DataChunk> MaterializedQueryResult::FetchRaw() {
|
|
|
110883
110966
|
|
|
110884
110967
|
|
|
110885
110968
|
|
|
110969
|
+
namespace duckdb {
|
|
110970
|
+
|
|
110971
|
+
PendingQueryResult::PendingQueryResult(shared_ptr<ClientContext> context_p, PreparedStatementData &statement,
|
|
110972
|
+
vector<LogicalType> types_p)
|
|
110973
|
+
: BaseQueryResult(QueryResultType::PENDING_RESULT, statement.statement_type, move(types_p), statement.names),
|
|
110974
|
+
context(move(context_p)) {
|
|
110975
|
+
}
|
|
110976
|
+
|
|
110977
|
+
PendingQueryResult::PendingQueryResult(string error) : BaseQueryResult(QueryResultType::PENDING_RESULT, move(error)) {
|
|
110978
|
+
}
|
|
110979
|
+
|
|
110980
|
+
PendingQueryResult::~PendingQueryResult() {
|
|
110981
|
+
}
|
|
110982
|
+
|
|
110983
|
+
unique_ptr<ClientContextLock> PendingQueryResult::LockContext() {
|
|
110984
|
+
if (!context) {
|
|
110985
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
110986
|
+
error);
|
|
110987
|
+
}
|
|
110988
|
+
return context->LockContext();
|
|
110989
|
+
}
|
|
110990
|
+
|
|
110991
|
+
void PendingQueryResult::CheckExecutableInternal(ClientContextLock &lock) {
|
|
110992
|
+
bool invalidated = !success || !context;
|
|
110993
|
+
if (!invalidated) {
|
|
110994
|
+
invalidated = !context->IsActiveResult(lock, this);
|
|
110995
|
+
}
|
|
110996
|
+
if (invalidated) {
|
|
110997
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
110998
|
+
error);
|
|
110999
|
+
}
|
|
111000
|
+
}
|
|
111001
|
+
|
|
111002
|
+
PendingExecutionResult PendingQueryResult::ExecuteTask() {
|
|
111003
|
+
auto lock = LockContext();
|
|
111004
|
+
return ExecuteTaskInternal(*lock);
|
|
111005
|
+
}
|
|
111006
|
+
|
|
111007
|
+
PendingExecutionResult PendingQueryResult::ExecuteTaskInternal(ClientContextLock &lock) {
|
|
111008
|
+
CheckExecutableInternal(lock);
|
|
111009
|
+
return context->ExecuteTaskInternal(lock, *this);
|
|
111010
|
+
}
|
|
111011
|
+
|
|
111012
|
+
unique_ptr<QueryResult> PendingQueryResult::ExecuteInternal(ClientContextLock &lock, bool allow_streaming_result) {
|
|
111013
|
+
CheckExecutableInternal(lock);
|
|
111014
|
+
while (ExecuteTaskInternal(lock) == PendingExecutionResult::RESULT_NOT_READY) {
|
|
111015
|
+
}
|
|
111016
|
+
if (!success) {
|
|
111017
|
+
return make_unique<MaterializedQueryResult>(error);
|
|
111018
|
+
}
|
|
111019
|
+
auto result = context->FetchResultInternal(lock, *this, allow_streaming_result);
|
|
111020
|
+
Close();
|
|
111021
|
+
return result;
|
|
111022
|
+
}
|
|
111023
|
+
|
|
111024
|
+
unique_ptr<QueryResult> PendingQueryResult::Execute(bool allow_streaming_result) {
|
|
111025
|
+
auto lock = LockContext();
|
|
111026
|
+
return ExecuteInternal(*lock, allow_streaming_result);
|
|
111027
|
+
}
|
|
111028
|
+
|
|
111029
|
+
void PendingQueryResult::Close() {
|
|
111030
|
+
context.reset();
|
|
111031
|
+
}
|
|
111032
|
+
|
|
111033
|
+
} // namespace duckdb
|
|
111034
|
+
|
|
111035
|
+
|
|
111036
|
+
|
|
111037
|
+
|
|
110886
111038
|
|
|
110887
111039
|
namespace duckdb {
|
|
110888
111040
|
|
|
@@ -110919,11 +111071,19 @@ const vector<string> &PreparedStatement::GetNames() {
|
|
|
110919
111071
|
}
|
|
110920
111072
|
|
|
110921
111073
|
unique_ptr<QueryResult> PreparedStatement::Execute(vector<Value> &values, bool allow_stream_result) {
|
|
111074
|
+
auto pending = PendingQuery(values);
|
|
111075
|
+
if (!pending->success) {
|
|
111076
|
+
return make_unique<MaterializedQueryResult>(pending->error);
|
|
111077
|
+
}
|
|
111078
|
+
return pending->Execute(allow_stream_result && data->allow_stream_result);
|
|
111079
|
+
}
|
|
111080
|
+
|
|
111081
|
+
unique_ptr<PendingQueryResult> PreparedStatement::PendingQuery(vector<Value> &values) {
|
|
110922
111082
|
if (!success) {
|
|
110923
111083
|
throw InvalidInputException("Attempting to execute an unsuccessfully prepared statement!");
|
|
110924
111084
|
}
|
|
110925
111085
|
D_ASSERT(data);
|
|
110926
|
-
auto result = context->
|
|
111086
|
+
auto result = context->PendingQuery(query, data, values);
|
|
110927
111087
|
return result;
|
|
110928
111088
|
}
|
|
110929
111089
|
|
|
@@ -111009,16 +111169,42 @@ using std::ofstream;
|
|
|
111009
111169
|
|
|
111010
111170
|
|
|
111011
111171
|
|
|
111172
|
+
|
|
111173
|
+
|
|
111012
111174
|
#include <utility>
|
|
111013
111175
|
#include <algorithm>
|
|
111014
111176
|
|
|
111015
111177
|
namespace duckdb {
|
|
111016
111178
|
|
|
111179
|
+
QueryProfiler::QueryProfiler(ClientContext &context_p)
|
|
111180
|
+
: context(context_p), running(false), query_requires_profiling(false), is_explain_analyze(false) {
|
|
111181
|
+
}
|
|
111182
|
+
|
|
111183
|
+
bool QueryProfiler::IsEnabled() const {
|
|
111184
|
+
return is_explain_analyze ? true : ClientConfig::GetConfig(context).enable_profiler;
|
|
111185
|
+
}
|
|
111186
|
+
|
|
111187
|
+
bool QueryProfiler::IsDetailedEnabled() const {
|
|
111188
|
+
return is_explain_analyze ? false : ClientConfig::GetConfig(context).enable_detailed_profiling;
|
|
111189
|
+
}
|
|
111190
|
+
|
|
111191
|
+
ProfilerPrintFormat QueryProfiler::GetPrintFormat() const {
|
|
111192
|
+
return is_explain_analyze ? ProfilerPrintFormat::NONE : ClientConfig::GetConfig(context).profiler_print_format;
|
|
111193
|
+
}
|
|
111194
|
+
|
|
111195
|
+
string QueryProfiler::GetSaveLocation() const {
|
|
111196
|
+
return is_explain_analyze ? string() : ClientConfig::GetConfig(context).profiler_save_location;
|
|
111197
|
+
}
|
|
111198
|
+
|
|
111199
|
+
QueryProfiler &QueryProfiler::Get(ClientContext &context) {
|
|
111200
|
+
return *context.profiler;
|
|
111201
|
+
}
|
|
111202
|
+
|
|
111017
111203
|
void QueryProfiler::StartQuery(string query, bool is_explain_analyze) {
|
|
111018
111204
|
if (is_explain_analyze) {
|
|
111019
111205
|
StartExplainAnalyze();
|
|
111020
111206
|
}
|
|
111021
|
-
if (!
|
|
111207
|
+
if (!IsEnabled()) {
|
|
111022
111208
|
return;
|
|
111023
111209
|
}
|
|
111024
111210
|
this->running = true;
|
|
@@ -111076,17 +111262,10 @@ void QueryProfiler::Finalize(TreeNode &node) {
|
|
|
111076
111262
|
|
|
111077
111263
|
void QueryProfiler::StartExplainAnalyze() {
|
|
111078
111264
|
this->is_explain_analyze = true;
|
|
111079
|
-
this->stored_enabled = enabled;
|
|
111080
|
-
this->stored_automatic_print_format = automatic_print_format;
|
|
111081
|
-
this->stored_save_location = save_location;
|
|
111082
|
-
|
|
111083
|
-
this->enabled = true;
|
|
111084
|
-
this->save_location = string();
|
|
111085
|
-
this->automatic_print_format = ProfilerPrintFormat::NONE;
|
|
111086
111265
|
}
|
|
111087
111266
|
|
|
111088
111267
|
void QueryProfiler::EndQuery() {
|
|
111089
|
-
if (!
|
|
111268
|
+
if (!IsEnabled() || !running) {
|
|
111090
111269
|
return;
|
|
111091
111270
|
}
|
|
111092
111271
|
|
|
@@ -111095,6 +111274,7 @@ void QueryProfiler::EndQuery() {
|
|
|
111095
111274
|
Finalize(*root);
|
|
111096
111275
|
}
|
|
111097
111276
|
this->running = false;
|
|
111277
|
+
auto automatic_print_format = GetPrintFormat();
|
|
111098
111278
|
// print or output the query profiling after termination, if this is enabled
|
|
111099
111279
|
if (automatic_print_format != ProfilerPrintFormat::NONE) {
|
|
111100
111280
|
// check if this query should be output based on the operator types
|
|
@@ -111106,7 +111286,7 @@ void QueryProfiler::EndQuery() {
|
|
|
111106
111286
|
} else if (automatic_print_format == ProfilerPrintFormat::QUERY_TREE_OPTIMIZER) {
|
|
111107
111287
|
query_info = ToString(true);
|
|
111108
111288
|
}
|
|
111109
|
-
|
|
111289
|
+
auto save_location = GetSaveLocation();
|
|
111110
111290
|
if (save_location.empty()) {
|
|
111111
111291
|
Printer::Print(query_info);
|
|
111112
111292
|
Printer::Print("\n");
|
|
@@ -111114,16 +111294,11 @@ void QueryProfiler::EndQuery() {
|
|
|
111114
111294
|
WriteToFile(save_location.c_str(), query_info);
|
|
111115
111295
|
}
|
|
111116
111296
|
}
|
|
111117
|
-
|
|
111118
|
-
this->is_explain_analyze = false;
|
|
111119
|
-
this->enabled = stored_enabled;
|
|
111120
|
-
this->automatic_print_format = stored_automatic_print_format;
|
|
111121
|
-
this->save_location = stored_save_location;
|
|
111122
|
-
}
|
|
111297
|
+
this->is_explain_analyze = false;
|
|
111123
111298
|
}
|
|
111124
111299
|
|
|
111125
111300
|
void QueryProfiler::StartPhase(string new_phase) {
|
|
111126
|
-
if (!
|
|
111301
|
+
if (!IsEnabled() || !running) {
|
|
111127
111302
|
return;
|
|
111128
111303
|
}
|
|
111129
111304
|
|
|
@@ -111147,7 +111322,7 @@ void QueryProfiler::StartPhase(string new_phase) {
|
|
|
111147
111322
|
}
|
|
111148
111323
|
|
|
111149
111324
|
void QueryProfiler::EndPhase() {
|
|
111150
|
-
if (!
|
|
111325
|
+
if (!IsEnabled() || !running) {
|
|
111151
111326
|
return;
|
|
111152
111327
|
}
|
|
111153
111328
|
D_ASSERT(phase_stack.size() > 0);
|
|
@@ -111167,7 +111342,7 @@ void QueryProfiler::EndPhase() {
|
|
|
111167
111342
|
}
|
|
111168
111343
|
|
|
111169
111344
|
void QueryProfiler::Initialize(PhysicalOperator *root_op) {
|
|
111170
|
-
if (!
|
|
111345
|
+
if (!IsEnabled() || !running) {
|
|
111171
111346
|
return;
|
|
111172
111347
|
}
|
|
111173
111348
|
this->query_requires_profiling = false;
|
|
@@ -111248,7 +111423,7 @@ void OperatorProfiler::Flush(const PhysicalOperator *phys_op, ExpressionExecutor
|
|
|
111248
111423
|
}
|
|
111249
111424
|
|
|
111250
111425
|
void QueryProfiler::Flush(OperatorProfiler &profiler) {
|
|
111251
|
-
if (!
|
|
111426
|
+
if (!IsEnabled() || !running) {
|
|
111252
111427
|
return;
|
|
111253
111428
|
}
|
|
111254
111429
|
lock_guard<mutex> guard(flush_lock);
|
|
@@ -111258,7 +111433,7 @@ void QueryProfiler::Flush(OperatorProfiler &profiler) {
|
|
|
111258
111433
|
|
|
111259
111434
|
entry->second->info.time += node.second.time;
|
|
111260
111435
|
entry->second->info.elements += node.second.elements;
|
|
111261
|
-
if (!
|
|
111436
|
+
if (!IsDetailedEnabled()) {
|
|
111262
111437
|
continue;
|
|
111263
111438
|
}
|
|
111264
111439
|
for (auto &info : node.second.executors_info) {
|
|
@@ -111319,7 +111494,7 @@ string QueryProfiler::ToString(bool print_optimizer_output) const {
|
|
|
111319
111494
|
}
|
|
111320
111495
|
|
|
111321
111496
|
void QueryProfiler::ToStream(std::ostream &ss, bool print_optimizer_output) const {
|
|
111322
|
-
if (!
|
|
111497
|
+
if (!IsEnabled()) {
|
|
111323
111498
|
ss << "Query profiling is disabled. Call "
|
|
111324
111499
|
"Connection::EnableProfiling() to enable profiling!";
|
|
111325
111500
|
return;
|
|
@@ -111490,7 +111665,7 @@ static void ToJSONRecursive(QueryProfiler::TreeNode &node, std::ostream &ss, int
|
|
|
111490
111665
|
}
|
|
111491
111666
|
|
|
111492
111667
|
string QueryProfiler::ToJSON() const {
|
|
111493
|
-
if (!
|
|
111668
|
+
if (!IsEnabled()) {
|
|
111494
111669
|
return "{ \"result\": \"disabled\" }\n";
|
|
111495
111670
|
}
|
|
111496
111671
|
if (query.empty()) {
|
|
@@ -111605,10 +111780,6 @@ vector<QueryProfiler::PhaseTimingItem> QueryProfiler::GetOrderedPhaseTimings() c
|
|
|
111605
111780
|
return result;
|
|
111606
111781
|
}
|
|
111607
111782
|
void QueryProfiler::Propagate(QueryProfiler &qp) {
|
|
111608
|
-
this->automatic_print_format = qp.automatic_print_format;
|
|
111609
|
-
this->save_location = qp.save_location;
|
|
111610
|
-
this->enabled = qp.enabled;
|
|
111611
|
-
this->detailed_enabled = qp.detailed_enabled;
|
|
111612
111783
|
}
|
|
111613
111784
|
|
|
111614
111785
|
void ExpressionInfo::ExtractExpressionsRecursive(unique_ptr<ExpressionState> &state) {
|
|
@@ -111665,17 +111836,44 @@ ExpressionRootInfo::ExpressionRootInfo(ExpressionExecutorState &state, string na
|
|
|
111665
111836
|
|
|
111666
111837
|
namespace duckdb {
|
|
111667
111838
|
|
|
111668
|
-
|
|
111839
|
+
BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type)
|
|
111669
111840
|
: type(type), statement_type(statement_type), success(true) {
|
|
111670
111841
|
}
|
|
111671
111842
|
|
|
111672
|
-
|
|
111673
|
-
|
|
111843
|
+
BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type, vector<LogicalType> types_p,
|
|
111844
|
+
vector<string> names_p)
|
|
111674
111845
|
: type(type), statement_type(statement_type), types(move(types_p)), names(move(names_p)), success(true) {
|
|
111675
111846
|
D_ASSERT(types.size() == names.size());
|
|
111676
111847
|
}
|
|
111677
111848
|
|
|
111678
|
-
|
|
111849
|
+
BaseQueryResult::BaseQueryResult(QueryResultType type, string error) : type(type), success(false), error(move(error)) {
|
|
111850
|
+
}
|
|
111851
|
+
|
|
111852
|
+
BaseQueryResult::~BaseQueryResult() {
|
|
111853
|
+
}
|
|
111854
|
+
|
|
111855
|
+
bool BaseQueryResult::HasError() {
|
|
111856
|
+
return !success;
|
|
111857
|
+
}
|
|
111858
|
+
const string &BaseQueryResult::GetError() {
|
|
111859
|
+
return error;
|
|
111860
|
+
}
|
|
111861
|
+
idx_t BaseQueryResult::ColumnCount() {
|
|
111862
|
+
return types.size();
|
|
111863
|
+
}
|
|
111864
|
+
|
|
111865
|
+
QueryResult::QueryResult(QueryResultType type, StatementType statement_type) : BaseQueryResult(type, statement_type) {
|
|
111866
|
+
}
|
|
111867
|
+
|
|
111868
|
+
QueryResult::QueryResult(QueryResultType type, StatementType statement_type, vector<LogicalType> types_p,
|
|
111869
|
+
vector<string> names_p)
|
|
111870
|
+
: BaseQueryResult(type, statement_type, move(types_p), move(names_p)) {
|
|
111871
|
+
}
|
|
111872
|
+
|
|
111873
|
+
QueryResult::QueryResult(QueryResultType type, string error) : BaseQueryResult(type, move(error)) {
|
|
111874
|
+
}
|
|
111875
|
+
|
|
111876
|
+
QueryResult::~QueryResult() {
|
|
111679
111877
|
}
|
|
111680
111878
|
|
|
111681
111879
|
unique_ptr<DataChunk> QueryResult::Fetch() {
|
|
@@ -114694,24 +114892,27 @@ Value EnableObjectCacheSetting::GetSetting(ClientContext &context) {
|
|
|
114694
114892
|
//===--------------------------------------------------------------------===//
|
|
114695
114893
|
void EnableProfilingSetting::SetLocal(ClientContext &context, const Value &input) {
|
|
114696
114894
|
auto parameter = StringUtil::Lower(input.ToString());
|
|
114895
|
+
|
|
114896
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
114697
114897
|
if (parameter == "json") {
|
|
114698
|
-
|
|
114898
|
+
config.profiler_print_format = ProfilerPrintFormat::JSON;
|
|
114699
114899
|
} else if (parameter == "query_tree") {
|
|
114700
|
-
|
|
114900
|
+
config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE;
|
|
114701
114901
|
} else if (parameter == "query_tree_optimizer") {
|
|
114702
|
-
|
|
114902
|
+
config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE_OPTIMIZER;
|
|
114703
114903
|
} else {
|
|
114704
114904
|
throw ParserException(
|
|
114705
114905
|
"Unrecognized print format %s, supported formats: [json, query_tree, query_tree_optimizer]", parameter);
|
|
114706
114906
|
}
|
|
114707
|
-
|
|
114907
|
+
config.enable_profiler = true;
|
|
114708
114908
|
}
|
|
114709
114909
|
|
|
114710
114910
|
Value EnableProfilingSetting::GetSetting(ClientContext &context) {
|
|
114711
|
-
|
|
114911
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
114912
|
+
if (!config.enable_profiler) {
|
|
114712
114913
|
return Value();
|
|
114713
114914
|
}
|
|
114714
|
-
switch (
|
|
114915
|
+
switch (config.profiler_print_format) {
|
|
114715
114916
|
case ProfilerPrintFormat::NONE:
|
|
114716
114917
|
return Value("none");
|
|
114717
114918
|
case ProfilerPrintFormat::JSON:
|
|
@@ -114855,12 +115056,14 @@ Value ProfilerHistorySize::GetSetting(ClientContext &context) {
|
|
|
114855
115056
|
// Profile Output
|
|
114856
115057
|
//===--------------------------------------------------------------------===//
|
|
114857
115058
|
void ProfileOutputSetting::SetLocal(ClientContext &context, const Value &input) {
|
|
115059
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
114858
115060
|
auto parameter = input.ToString();
|
|
114859
|
-
|
|
115061
|
+
config.profiler_save_location = parameter;
|
|
114860
115062
|
}
|
|
114861
115063
|
|
|
114862
115064
|
Value ProfileOutputSetting::GetSetting(ClientContext &context) {
|
|
114863
|
-
|
|
115065
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
115066
|
+
return Value(config.profiler_save_location);
|
|
114864
115067
|
}
|
|
114865
115068
|
|
|
114866
115069
|
//===--------------------------------------------------------------------===//
|
|
@@ -114868,17 +115071,24 @@ Value ProfileOutputSetting::GetSetting(ClientContext &context) {
|
|
|
114868
115071
|
//===--------------------------------------------------------------------===//
|
|
114869
115072
|
void ProfilingModeSetting::SetLocal(ClientContext &context, const Value &input) {
|
|
114870
115073
|
auto parameter = StringUtil::Lower(input.ToString());
|
|
115074
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
114871
115075
|
if (parameter == "standard") {
|
|
114872
|
-
|
|
115076
|
+
config.enable_profiler = true;
|
|
115077
|
+
config.enable_detailed_profiling = false;
|
|
114873
115078
|
} else if (parameter == "detailed") {
|
|
114874
|
-
|
|
115079
|
+
config.enable_profiler = true;
|
|
115080
|
+
config.enable_detailed_profiling = true;
|
|
114875
115081
|
} else {
|
|
114876
115082
|
throw ParserException("Unrecognized profiling mode \"%s\", supported formats: [standard, detailed]", parameter);
|
|
114877
115083
|
}
|
|
114878
115084
|
}
|
|
114879
115085
|
|
|
114880
115086
|
Value ProfilingModeSetting::GetSetting(ClientContext &context) {
|
|
114881
|
-
|
|
115087
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
115088
|
+
if (!config.enable_profiler) {
|
|
115089
|
+
return Value();
|
|
115090
|
+
}
|
|
115091
|
+
return Value(config.enable_detailed_profiling ? "detailed" : "standard");
|
|
114882
115092
|
}
|
|
114883
115093
|
|
|
114884
115094
|
//===--------------------------------------------------------------------===//
|
|
@@ -114958,14 +115168,11 @@ Value ThreadsSetting::GetSetting(ClientContext &context) {
|
|
|
114958
115168
|
namespace duckdb {
|
|
114959
115169
|
|
|
114960
115170
|
StreamQueryResult::StreamQueryResult(StatementType statement_type, shared_ptr<ClientContext> context,
|
|
114961
|
-
vector<LogicalType> types, vector<string> names
|
|
114962
|
-
|
|
114963
|
-
: QueryResult(QueryResultType::STREAM_RESULT, statement_type, move(types), move(names)), is_open(true),
|
|
114964
|
-
context(move(context)), prepared(move(prepared)) {
|
|
115171
|
+
vector<LogicalType> types, vector<string> names)
|
|
115172
|
+
: QueryResult(QueryResultType::STREAM_RESULT, statement_type, move(types), move(names)), context(move(context)) {
|
|
114965
115173
|
}
|
|
114966
115174
|
|
|
114967
115175
|
StreamQueryResult::~StreamQueryResult() {
|
|
114968
|
-
Close();
|
|
114969
115176
|
}
|
|
114970
115177
|
|
|
114971
115178
|
string StreamQueryResult::ToString() {
|
|
@@ -114979,12 +115186,28 @@ string StreamQueryResult::ToString() {
|
|
|
114979
115186
|
return result;
|
|
114980
115187
|
}
|
|
114981
115188
|
|
|
115189
|
+
unique_ptr<ClientContextLock> StreamQueryResult::LockContext() {
|
|
115190
|
+
if (!context) {
|
|
115191
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
115192
|
+
error);
|
|
115193
|
+
}
|
|
115194
|
+
return context->LockContext();
|
|
115195
|
+
}
|
|
115196
|
+
|
|
115197
|
+
void StreamQueryResult::CheckExecutableInternal(ClientContextLock &lock) {
|
|
115198
|
+
if (!IsOpenInternal(lock)) {
|
|
115199
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
115200
|
+
error);
|
|
115201
|
+
}
|
|
115202
|
+
}
|
|
115203
|
+
|
|
114982
115204
|
unique_ptr<DataChunk> StreamQueryResult::FetchRaw() {
|
|
114983
|
-
|
|
114984
|
-
|
|
114985
|
-
|
|
115205
|
+
unique_ptr<DataChunk> chunk;
|
|
115206
|
+
{
|
|
115207
|
+
auto lock = LockContext();
|
|
115208
|
+
CheckExecutableInternal(*lock);
|
|
115209
|
+
chunk = context->Fetch(*lock, *this);
|
|
114986
115210
|
}
|
|
114987
|
-
auto chunk = context->Fetch();
|
|
114988
115211
|
if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) {
|
|
114989
115212
|
Close();
|
|
114990
115213
|
return nullptr;
|
|
@@ -115010,12 +115233,24 @@ unique_ptr<MaterializedQueryResult> StreamQueryResult::Materialize() {
|
|
|
115010
115233
|
return result;
|
|
115011
115234
|
}
|
|
115012
115235
|
|
|
115013
|
-
|
|
115014
|
-
|
|
115015
|
-
|
|
115236
|
+
bool StreamQueryResult::IsOpenInternal(ClientContextLock &lock) {
|
|
115237
|
+
bool invalidated = !success || !context;
|
|
115238
|
+
if (!invalidated) {
|
|
115239
|
+
invalidated = !context->IsActiveResult(lock, this);
|
|
115016
115240
|
}
|
|
115017
|
-
|
|
115018
|
-
|
|
115241
|
+
return !invalidated;
|
|
115242
|
+
}
|
|
115243
|
+
|
|
115244
|
+
bool StreamQueryResult::IsOpen() {
|
|
115245
|
+
if (!success || !context) {
|
|
115246
|
+
return false;
|
|
115247
|
+
}
|
|
115248
|
+
auto lock = LockContext();
|
|
115249
|
+
return IsOpenInternal(*lock);
|
|
115250
|
+
}
|
|
115251
|
+
|
|
115252
|
+
void StreamQueryResult::Close() {
|
|
115253
|
+
context.reset();
|
|
115019
115254
|
}
|
|
115020
115255
|
|
|
115021
115256
|
} // namespace duckdb
|
|
@@ -119810,9 +120045,10 @@ void Optimizer::RunOptimizer(OptimizerType type, const std::function<void()> &ca
|
|
|
119810
120045
|
// optimizer is marked as disabled: skip
|
|
119811
120046
|
return;
|
|
119812
120047
|
}
|
|
119813
|
-
|
|
120048
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
120049
|
+
profiler.StartPhase(OptimizerTypeToString(type));
|
|
119814
120050
|
callback();
|
|
119815
|
-
|
|
120051
|
+
profiler.EndPhase();
|
|
119816
120052
|
}
|
|
119817
120053
|
|
|
119818
120054
|
unique_ptr<LogicalOperator> Optimizer::Optimize(unique_ptr<LogicalOperator> plan) {
|
|
@@ -123771,6 +124007,10 @@ public:
|
|
|
123771
124007
|
|
|
123772
124008
|
//! Fully execute a pipeline with a source and a sink until the source is completely exhausted
|
|
123773
124009
|
void Execute();
|
|
124010
|
+
//! Execute a pipeline with a source and a sink until finished, or until max_chunks have been processed
|
|
124011
|
+
//! Returns true if execution is finished, false if Execute should be called again
|
|
124012
|
+
bool Execute(idx_t max_chunks);
|
|
124013
|
+
|
|
123774
124014
|
//! Push a single input DataChunk into the pipeline.
|
|
123775
124015
|
//! Returns either OperatorResultType::NEED_MORE_INPUT or OperatorResultType::FINISHED
|
|
123776
124016
|
//! If OperatorResultType::FINISHED is returned, more input will not change the result anymore
|
|
@@ -123939,7 +124179,7 @@ Executor::~Executor() {
|
|
|
123939
124179
|
}
|
|
123940
124180
|
|
|
123941
124181
|
Executor &Executor::Get(ClientContext &context) {
|
|
123942
|
-
return context.
|
|
124182
|
+
return context.GetExecutor();
|
|
123943
124183
|
}
|
|
123944
124184
|
|
|
123945
124185
|
void Executor::AddEvent(shared_ptr<Event> event) {
|
|
@@ -124168,16 +124408,6 @@ void Executor::VerifyPipelines() {
|
|
|
124168
124408
|
#endif
|
|
124169
124409
|
}
|
|
124170
124410
|
|
|
124171
|
-
void Executor::WorkOnTasks() {
|
|
124172
|
-
auto &scheduler = TaskScheduler::GetScheduler(context);
|
|
124173
|
-
|
|
124174
|
-
unique_ptr<Task> task;
|
|
124175
|
-
while (scheduler.GetTaskFromProducer(*producer, task)) {
|
|
124176
|
-
task->Execute();
|
|
124177
|
-
task.reset();
|
|
124178
|
-
}
|
|
124179
|
-
}
|
|
124180
|
-
|
|
124181
124411
|
void Executor::Initialize(PhysicalOperator *plan) {
|
|
124182
124412
|
Reset();
|
|
124183
124413
|
|
|
@@ -124186,7 +124416,8 @@ void Executor::Initialize(PhysicalOperator *plan) {
|
|
|
124186
124416
|
lock_guard<mutex> elock(executor_lock);
|
|
124187
124417
|
physical_plan = plan;
|
|
124188
124418
|
|
|
124189
|
-
|
|
124419
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
124420
|
+
profiler.Initialize(physical_plan);
|
|
124190
124421
|
this->producer = scheduler.CreateProducer();
|
|
124191
124422
|
|
|
124192
124423
|
auto root_pipeline = make_shared<Pipeline>(*this);
|
|
@@ -124202,60 +124433,102 @@ void Executor::Initialize(PhysicalOperator *plan) {
|
|
|
124202
124433
|
|
|
124203
124434
|
ScheduleEvents();
|
|
124204
124435
|
}
|
|
124436
|
+
}
|
|
124205
124437
|
|
|
124206
|
-
|
|
124207
|
-
|
|
124208
|
-
|
|
124209
|
-
|
|
124210
|
-
|
|
124211
|
-
|
|
124438
|
+
void Executor::CancelTasks() {
|
|
124439
|
+
task.reset();
|
|
124440
|
+
// we do this by creating weak pointers to all pipelines
|
|
124441
|
+
// then clearing our references to the pipelines
|
|
124442
|
+
// and waiting until all pipelines have been destroyed
|
|
124443
|
+
vector<weak_ptr<Pipeline>> weak_references;
|
|
124444
|
+
{
|
|
124445
|
+
lock_guard<mutex> elock(executor_lock);
|
|
124446
|
+
if (pipelines.empty()) {
|
|
124447
|
+
return;
|
|
124212
124448
|
}
|
|
124213
|
-
|
|
124214
|
-
|
|
124215
|
-
|
|
124216
|
-
|
|
124217
|
-
|
|
124218
|
-
|
|
124219
|
-
vector<weak_ptr<Pipeline>> weak_references;
|
|
124220
|
-
{
|
|
124221
|
-
lock_guard<mutex> elock(executor_lock);
|
|
124222
|
-
weak_references.reserve(pipelines.size());
|
|
124223
|
-
for (auto &pipeline : pipelines) {
|
|
124449
|
+
weak_references.reserve(pipelines.size());
|
|
124450
|
+
for (auto &pipeline : pipelines) {
|
|
124451
|
+
weak_references.push_back(weak_ptr<Pipeline>(pipeline));
|
|
124452
|
+
}
|
|
124453
|
+
for (auto &kv : union_pipelines) {
|
|
124454
|
+
for (auto &pipeline : kv.second) {
|
|
124224
124455
|
weak_references.push_back(weak_ptr<Pipeline>(pipeline));
|
|
124225
124456
|
}
|
|
124226
|
-
|
|
124227
|
-
|
|
124228
|
-
|
|
124229
|
-
|
|
124457
|
+
}
|
|
124458
|
+
for (auto &kv : child_pipelines) {
|
|
124459
|
+
for (auto &pipeline : kv.second) {
|
|
124460
|
+
weak_references.push_back(weak_ptr<Pipeline>(pipeline));
|
|
124230
124461
|
}
|
|
124231
|
-
|
|
124232
|
-
|
|
124233
|
-
|
|
124234
|
-
|
|
124462
|
+
}
|
|
124463
|
+
pipelines.clear();
|
|
124464
|
+
union_pipelines.clear();
|
|
124465
|
+
child_pipelines.clear();
|
|
124466
|
+
events.clear();
|
|
124467
|
+
}
|
|
124468
|
+
WorkOnTasks();
|
|
124469
|
+
for (auto &weak_ref : weak_references) {
|
|
124470
|
+
while (true) {
|
|
124471
|
+
auto weak = weak_ref.lock();
|
|
124472
|
+
if (!weak) {
|
|
124473
|
+
break;
|
|
124235
124474
|
}
|
|
124236
|
-
pipelines.clear();
|
|
124237
|
-
union_pipelines.clear();
|
|
124238
|
-
child_pipelines.clear();
|
|
124239
|
-
events.clear();
|
|
124240
124475
|
}
|
|
124241
|
-
|
|
124242
|
-
|
|
124243
|
-
|
|
124244
|
-
|
|
124245
|
-
|
|
124246
|
-
|
|
124476
|
+
}
|
|
124477
|
+
}
|
|
124478
|
+
|
|
124479
|
+
void Executor::WorkOnTasks() {
|
|
124480
|
+
auto &scheduler = TaskScheduler::GetScheduler(context);
|
|
124481
|
+
|
|
124482
|
+
unique_ptr<Task> task;
|
|
124483
|
+
while (scheduler.GetTaskFromProducer(*producer, task)) {
|
|
124484
|
+
task->Execute(TaskExecutionMode::PROCESS_ALL);
|
|
124485
|
+
task.reset();
|
|
124486
|
+
}
|
|
124487
|
+
}
|
|
124488
|
+
|
|
124489
|
+
PendingExecutionResult Executor::ExecuteTask() {
|
|
124490
|
+
if (execution_result != PendingExecutionResult::RESULT_NOT_READY) {
|
|
124491
|
+
return execution_result;
|
|
124492
|
+
}
|
|
124493
|
+
// check if there are any incomplete pipelines
|
|
124494
|
+
auto &scheduler = TaskScheduler::GetScheduler(context);
|
|
124495
|
+
while (completed_pipelines < total_pipelines) {
|
|
124496
|
+
// there are! if we don't already have a task, fetch one
|
|
124497
|
+
if (!task) {
|
|
124498
|
+
scheduler.GetTaskFromProducer(*producer, task);
|
|
124499
|
+
}
|
|
124500
|
+
if (task) {
|
|
124501
|
+
// if we have a task, partially process it
|
|
124502
|
+
auto result = task->Execute(TaskExecutionMode::PROCESS_PARTIAL);
|
|
124503
|
+
if (result != TaskExecutionResult::TASK_NOT_FINISHED) {
|
|
124504
|
+
// if the task is finished, clean it up
|
|
124505
|
+
task.reset();
|
|
124247
124506
|
}
|
|
124248
124507
|
}
|
|
124508
|
+
if (!HasError()) {
|
|
124509
|
+
// we (partially) processed a task and no exceptions were thrown
|
|
124510
|
+
// give back control to the caller
|
|
124511
|
+
return PendingExecutionResult::RESULT_NOT_READY;
|
|
124512
|
+
}
|
|
124513
|
+
execution_result = PendingExecutionResult::EXECUTION_ERROR;
|
|
124514
|
+
|
|
124515
|
+
// an exception has occurred executing one of the pipelines
|
|
124516
|
+
// we need to cancel all tasks associated with this executor
|
|
124517
|
+
CancelTasks();
|
|
124249
124518
|
ThrowException();
|
|
124250
124519
|
}
|
|
124520
|
+
D_ASSERT(!task);
|
|
124251
124521
|
|
|
124252
124522
|
lock_guard<mutex> elock(executor_lock);
|
|
124253
124523
|
pipelines.clear();
|
|
124254
124524
|
NextExecutor();
|
|
124255
124525
|
if (!exceptions.empty()) { // LCOV_EXCL_START
|
|
124256
124526
|
// an exception has occurred executing one of the pipelines
|
|
124527
|
+
execution_result = PendingExecutionResult::EXECUTION_ERROR;
|
|
124257
124528
|
ThrowExceptionInternal();
|
|
124258
124529
|
} // LCOV_EXCL_STOP
|
|
124530
|
+
execution_result = PendingExecutionResult::RESULT_READY;
|
|
124531
|
+
return execution_result;
|
|
124259
124532
|
}
|
|
124260
124533
|
|
|
124261
124534
|
void Executor::Reset() {
|
|
@@ -124274,6 +124547,7 @@ void Executor::Reset() {
|
|
|
124274
124547
|
union_pipelines.clear();
|
|
124275
124548
|
child_pipelines.clear();
|
|
124276
124549
|
child_dependencies.clear();
|
|
124550
|
+
execution_result = PendingExecutionResult::RESULT_NOT_READY;
|
|
124277
124551
|
}
|
|
124278
124552
|
|
|
124279
124553
|
void Executor::AddChildPipeline(Pipeline *current) {
|
|
@@ -124555,10 +124829,11 @@ void Executor::ThrowExceptionInternal() { // LCOV_EXCL_START
|
|
|
124555
124829
|
|
|
124556
124830
|
void Executor::Flush(ThreadContext &tcontext) {
|
|
124557
124831
|
lock_guard<mutex> elock(executor_lock);
|
|
124558
|
-
|
|
124832
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
124833
|
+
profiler.Flush(tcontext.profiler);
|
|
124559
124834
|
}
|
|
124560
124835
|
|
|
124561
|
-
bool Executor::GetPipelinesProgress(
|
|
124836
|
+
bool Executor::GetPipelinesProgress(double ¤t_progress) { // LCOV_EXCL_START
|
|
124562
124837
|
lock_guard<mutex> elock(executor_lock);
|
|
124563
124838
|
|
|
124564
124839
|
if (!pipelines.empty()) {
|
|
@@ -124604,9 +124879,9 @@ ExecutorTask::ExecutorTask(ClientContext &context) : ExecutorTask(Executor::Get(
|
|
|
124604
124879
|
ExecutorTask::~ExecutorTask() {
|
|
124605
124880
|
}
|
|
124606
124881
|
|
|
124607
|
-
|
|
124882
|
+
TaskExecutionResult ExecutorTask::Execute(TaskExecutionMode mode) {
|
|
124608
124883
|
try {
|
|
124609
|
-
ExecuteTask();
|
|
124884
|
+
return ExecuteTask(mode);
|
|
124610
124885
|
} catch (Exception &ex) {
|
|
124611
124886
|
executor.PushError(ex.type, ex.what());
|
|
124612
124887
|
} catch (std::exception &ex) {
|
|
@@ -124614,6 +124889,7 @@ void ExecutorTask::Execute() {
|
|
|
124614
124889
|
} catch (...) { // LCOV_EXCL_START
|
|
124615
124890
|
executor.PushError(ExceptionType::UNKNOWN_TYPE, "Unknown exception in Finalize!");
|
|
124616
124891
|
} // LCOV_EXCL_STOP
|
|
124892
|
+
return TaskExecutionResult::TASK_ERROR;
|
|
124617
124893
|
}
|
|
124618
124894
|
|
|
124619
124895
|
} // namespace duckdb
|
|
@@ -124641,6 +124917,8 @@ void ExecutorTask::Execute() {
|
|
|
124641
124917
|
namespace duckdb {
|
|
124642
124918
|
|
|
124643
124919
|
class PipelineTask : public ExecutorTask {
|
|
124920
|
+
static constexpr const idx_t PARTIAL_CHUNK_COUNT = 50;
|
|
124921
|
+
|
|
124644
124922
|
public:
|
|
124645
124923
|
explicit PipelineTask(Pipeline &pipeline_p, shared_ptr<Event> event_p)
|
|
124646
124924
|
: ExecutorTask(pipeline_p.executor), pipeline(pipeline_p), event(move(event_p)) {
|
|
@@ -124648,12 +124926,24 @@ public:
|
|
|
124648
124926
|
|
|
124649
124927
|
Pipeline &pipeline;
|
|
124650
124928
|
shared_ptr<Event> event;
|
|
124929
|
+
unique_ptr<PipelineExecutor> pipeline_executor;
|
|
124651
124930
|
|
|
124652
124931
|
public:
|
|
124653
|
-
|
|
124654
|
-
|
|
124655
|
-
|
|
124932
|
+
TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override {
|
|
124933
|
+
if (!pipeline_executor) {
|
|
124934
|
+
pipeline_executor = make_unique<PipelineExecutor>(pipeline.GetClientContext(), pipeline);
|
|
124935
|
+
}
|
|
124936
|
+
if (mode == TaskExecutionMode::PROCESS_PARTIAL) {
|
|
124937
|
+
bool finished = pipeline_executor->Execute(PARTIAL_CHUNK_COUNT);
|
|
124938
|
+
if (!finished) {
|
|
124939
|
+
return TaskExecutionResult::TASK_NOT_FINISHED;
|
|
124940
|
+
}
|
|
124941
|
+
} else {
|
|
124942
|
+
pipeline_executor->Execute();
|
|
124943
|
+
}
|
|
124656
124944
|
event->FinishTask();
|
|
124945
|
+
pipeline_executor.reset();
|
|
124946
|
+
return TaskExecutionResult::TASK_FINISHED;
|
|
124657
124947
|
}
|
|
124658
124948
|
};
|
|
124659
124949
|
|
|
@@ -124665,7 +124955,7 @@ ClientContext &Pipeline::GetClientContext() {
|
|
|
124665
124955
|
}
|
|
124666
124956
|
|
|
124667
124957
|
// LCOV_EXCL_START
|
|
124668
|
-
bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op,
|
|
124958
|
+
bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op, double ¤t_percentage) {
|
|
124669
124959
|
current_percentage = -1;
|
|
124670
124960
|
switch (op->type) {
|
|
124671
124961
|
case PhysicalOperatorType::TABLE_SCAN: {
|
|
@@ -124684,7 +124974,7 @@ bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op,
|
|
|
124684
124974
|
}
|
|
124685
124975
|
// LCOV_EXCL_STOP
|
|
124686
124976
|
|
|
124687
|
-
bool Pipeline::GetProgress(
|
|
124977
|
+
bool Pipeline::GetProgress(double ¤t_percentage) {
|
|
124688
124978
|
auto &client = executor.context;
|
|
124689
124979
|
return GetProgressInternal(client, source, current_percentage);
|
|
124690
124980
|
}
|
|
@@ -124885,16 +125175,18 @@ PipelineExecutor::PipelineExecutor(ClientContext &context_p, Pipeline &pipeline_
|
|
|
124885
125175
|
InitializeChunk(final_chunk);
|
|
124886
125176
|
}
|
|
124887
125177
|
|
|
124888
|
-
|
|
125178
|
+
bool PipelineExecutor::Execute(idx_t max_chunks) {
|
|
124889
125179
|
D_ASSERT(pipeline.sink);
|
|
125180
|
+
bool exhausted_source = false;
|
|
124890
125181
|
auto &source_chunk = pipeline.operators.empty() ? final_chunk : *intermediate_chunks[0];
|
|
124891
|
-
|
|
125182
|
+
for (idx_t i = 0; i < max_chunks; i++) {
|
|
124892
125183
|
if (finished_processing) {
|
|
124893
125184
|
break;
|
|
124894
125185
|
}
|
|
124895
125186
|
source_chunk.Reset();
|
|
124896
125187
|
FetchFromSource(source_chunk);
|
|
124897
125188
|
if (source_chunk.size() == 0) {
|
|
125189
|
+
exhausted_source = true;
|
|
124898
125190
|
break;
|
|
124899
125191
|
}
|
|
124900
125192
|
auto result = ExecutePushInternal(source_chunk);
|
|
@@ -124903,7 +125195,15 @@ void PipelineExecutor::Execute() {
|
|
|
124903
125195
|
break;
|
|
124904
125196
|
}
|
|
124905
125197
|
}
|
|
125198
|
+
if (!exhausted_source && !finished_processing) {
|
|
125199
|
+
return false;
|
|
125200
|
+
}
|
|
124906
125201
|
PushFinalize();
|
|
125202
|
+
return true;
|
|
125203
|
+
}
|
|
125204
|
+
|
|
125205
|
+
void PipelineExecutor::Execute() {
|
|
125206
|
+
Execute(NumericLimits<idx_t>::Maximum());
|
|
124907
125207
|
}
|
|
124908
125208
|
|
|
124909
125209
|
OperatorResultType PipelineExecutor::ExecutePush(DataChunk &input) { // LCOV_EXCL_START
|
|
@@ -129434,7 +129734,7 @@ void TaskScheduler::ExecuteForever(atomic<bool> *marker) {
|
|
|
129434
129734
|
// wait for a signal with a timeout; the timeout allows us to periodically check
|
|
129435
129735
|
queue->semaphore.wait(TASK_TIMEOUT_USECS);
|
|
129436
129736
|
if (queue->q.try_dequeue(task)) {
|
|
129437
|
-
task->Execute();
|
|
129737
|
+
task->Execute(TaskExecutionMode::PROCESS_ALL);
|
|
129438
129738
|
task.reset();
|
|
129439
129739
|
}
|
|
129440
129740
|
}
|
|
@@ -129507,7 +129807,7 @@ void TaskScheduler::SetThreadsInternal(int32_t n) {
|
|
|
129507
129807
|
|
|
129508
129808
|
namespace duckdb {
|
|
129509
129809
|
|
|
129510
|
-
ThreadContext::ThreadContext(ClientContext &context) : profiler(context.
|
|
129810
|
+
ThreadContext::ThreadContext(ClientContext &context) : profiler(QueryProfiler::Get(context).IsEnabled()) {
|
|
129511
129811
|
}
|
|
129512
129812
|
|
|
129513
129813
|
} // namespace duckdb
|
|
@@ -154511,13 +154811,15 @@ Planner::Planner(ClientContext &context) : binder(Binder::CreateBinder(context))
|
|
|
154511
154811
|
}
|
|
154512
154812
|
|
|
154513
154813
|
void Planner::CreatePlan(SQLStatement &statement) {
|
|
154814
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
154815
|
+
|
|
154514
154816
|
vector<BoundParameterExpression *> bound_parameters;
|
|
154515
154817
|
|
|
154516
154818
|
// first bind the tables and columns to the catalog
|
|
154517
|
-
|
|
154819
|
+
profiler.StartPhase("binder");
|
|
154518
154820
|
binder->parameters = &bound_parameters;
|
|
154519
154821
|
auto bound_statement = binder->Bind(statement);
|
|
154520
|
-
|
|
154822
|
+
profiler.EndPhase();
|
|
154521
154823
|
|
|
154522
154824
|
this->read_only = binder->read_only;
|
|
154523
154825
|
this->requires_valid_transaction = binder->requires_valid_transaction;
|