duckdb 0.3.2-dev633.0 → 0.3.2-dev665.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 +1003 -517
- package/src/duckdb.hpp +5864 -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
|
|
24109
|
-
}
|
|
24110
|
-
|
|
24111
|
-
ProgressBar::~ProgressBar() {
|
|
24112
|
-
Stop();
|
|
24094
|
+
supported = true;
|
|
24113
24095
|
}
|
|
24114
24096
|
|
|
24115
|
-
void ProgressBar::
|
|
24116
|
-
|
|
24117
|
-
|
|
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
|
|
|
@@ -24923,8 +24915,8 @@ static void GatherNestedVector(Vector &rows, const SelectionVector &row_sel, Vec
|
|
|
24923
24915
|
auto ptrs = FlatVector::GetData<data_ptr_t>(rows);
|
|
24924
24916
|
|
|
24925
24917
|
// Build the gather locations
|
|
24926
|
-
|
|
24927
|
-
|
|
24918
|
+
auto data_locations = unique_ptr<data_ptr_t[]>(new data_ptr_t[count]);
|
|
24919
|
+
auto mask_locations = unique_ptr<data_ptr_t[]>(new data_ptr_t[count]);
|
|
24928
24920
|
for (idx_t i = 0; i < count; i++) {
|
|
24929
24921
|
auto row_idx = row_sel.get_index(i);
|
|
24930
24922
|
mask_locations[i] = ptrs[row_idx];
|
|
@@ -24932,7 +24924,7 @@ static void GatherNestedVector(Vector &rows, const SelectionVector &row_sel, Vec
|
|
|
24932
24924
|
}
|
|
24933
24925
|
|
|
24934
24926
|
// Deserialise into the selected locations
|
|
24935
|
-
RowOperations::HeapGather(col, count, col_sel, col_no, data_locations, mask_locations);
|
|
24927
|
+
RowOperations::HeapGather(col, count, col_sel, col_no, data_locations.get(), mask_locations.get());
|
|
24936
24928
|
}
|
|
24937
24929
|
|
|
24938
24930
|
void RowOperations::Gather(Vector &rows, const SelectionVector &row_sel, Vector &col, const SelectionVector &col_sel,
|
|
@@ -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
|
-
|
|
30527
|
+
DUCKDB_API bool IsEnabled() const;
|
|
30528
|
+
DUCKDB_API bool IsDetailedEnabled() const;
|
|
30529
|
+
DUCKDB_API ProfilerPrintFormat GetPrintFormat() const;
|
|
30530
|
+
DUCKDB_API string GetSaveLocation() const;
|
|
30596
30531
|
|
|
30597
|
-
DUCKDB_API
|
|
30598
|
-
detailed_enabled = true;
|
|
30599
|
-
}
|
|
30600
|
-
|
|
30601
|
-
DUCKDB_API void Disable() {
|
|
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;
|
|
@@ -37730,6 +37647,19 @@ T Value::GetValueInternal() const {
|
|
|
37730
37647
|
return Cast::Operation<interval_t, T>(value_.interval);
|
|
37731
37648
|
case LogicalTypeId::DECIMAL:
|
|
37732
37649
|
return CastAs(LogicalType::DOUBLE).GetValueInternal<T>();
|
|
37650
|
+
case LogicalTypeId::ENUM: {
|
|
37651
|
+
switch (type_.InternalType()) {
|
|
37652
|
+
case PhysicalType::UINT8:
|
|
37653
|
+
return Cast::Operation<uint8_t, T>(value_.utinyint);
|
|
37654
|
+
case PhysicalType::UINT16:
|
|
37655
|
+
return Cast::Operation<uint16_t, T>(value_.usmallint);
|
|
37656
|
+
case PhysicalType::UINT32:
|
|
37657
|
+
return Cast::Operation<uint32_t, T>(value_.uinteger);
|
|
37658
|
+
default:
|
|
37659
|
+
throw InternalException("Invalid Internal Type for ENUMs");
|
|
37660
|
+
}
|
|
37661
|
+
}
|
|
37662
|
+
|
|
37733
37663
|
default:
|
|
37734
37664
|
throw NotImplementedException("Unimplemented type \"%s\" for GetValue()", type_.ToString());
|
|
37735
37665
|
}
|
|
@@ -41627,12 +41557,15 @@ static bool TemplatedBooleanOperation(const Value &left, const Value &right) {
|
|
|
41627
41557
|
const auto &left_type = left.type();
|
|
41628
41558
|
const auto &right_type = right.type();
|
|
41629
41559
|
if (left_type != right_type) {
|
|
41630
|
-
|
|
41631
|
-
|
|
41632
|
-
|
|
41633
|
-
|
|
41560
|
+
Value left_copy = left;
|
|
41561
|
+
Value right_copy = right;
|
|
41562
|
+
|
|
41563
|
+
LogicalType comparison_type = BoundComparisonExpression::BindComparison(left_type, right_type);
|
|
41564
|
+
if (!left_copy.TryCastAs(comparison_type) || !right_copy.TryCastAs(comparison_type)) {
|
|
41634
41565
|
return false;
|
|
41635
41566
|
}
|
|
41567
|
+
D_ASSERT(left_copy.type() == right_copy.type());
|
|
41568
|
+
return TemplatedBooleanOperation<OP>(left_copy, right_copy);
|
|
41636
41569
|
}
|
|
41637
41570
|
switch (left_type.InternalType()) {
|
|
41638
41571
|
case PhysicalType::BOOL:
|
|
@@ -52680,8 +52613,9 @@ void PhysicalSimpleAggregate::Combine(ExecutionContext &context, GlobalSinkState
|
|
|
52680
52613
|
aggregate.function.combine(source_state, dest_state, 1);
|
|
52681
52614
|
}
|
|
52682
52615
|
|
|
52616
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
52683
52617
|
context.thread.profiler.Flush(this, &source.child_executor, "child_executor", 0);
|
|
52684
|
-
|
|
52618
|
+
client_profiler.Flush(context.thread.profiler);
|
|
52685
52619
|
}
|
|
52686
52620
|
|
|
52687
52621
|
SinkFinalizeType PhysicalSimpleAggregate::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
@@ -54486,7 +54420,8 @@ SinkResultType PhysicalExplainAnalyze::Sink(ExecutionContext &context, GlobalSin
|
|
|
54486
54420
|
SinkFinalizeType PhysicalExplainAnalyze::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
54487
54421
|
GlobalSinkState &gstate_p) const {
|
|
54488
54422
|
auto &gstate = (ExplainAnalyzeStateGlobalState &)gstate_p;
|
|
54489
|
-
|
|
54423
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
54424
|
+
gstate.analyzed_plan = profiler.ToString();
|
|
54490
54425
|
return SinkFinalizeType::READY;
|
|
54491
54426
|
}
|
|
54492
54427
|
|
|
@@ -57267,8 +57202,9 @@ SinkResultType PhysicalHashJoin::Sink(ExecutionContext &context, GlobalSinkState
|
|
|
57267
57202
|
|
|
57268
57203
|
void PhysicalHashJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
57269
57204
|
auto &state = (HashJoinLocalState &)lstate;
|
|
57205
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
57270
57206
|
context.thread.profiler.Flush(this, &state.build_executor, "build_executor", 1);
|
|
57271
|
-
|
|
57207
|
+
client_profiler.Flush(context.thread.profiler);
|
|
57272
57208
|
}
|
|
57273
57209
|
|
|
57274
57210
|
//===--------------------------------------------------------------------===//
|
|
@@ -58032,8 +57968,10 @@ SinkResultType PhysicalNestedLoopJoin::Sink(ExecutionContext &context, GlobalSin
|
|
|
58032
57968
|
|
|
58033
57969
|
void PhysicalNestedLoopJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
58034
57970
|
auto &state = (NestedLoopJoinLocalState &)lstate;
|
|
57971
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
57972
|
+
|
|
58035
57973
|
context.thread.profiler.Flush(this, &state.rhs_executor, "rhs_executor", 1);
|
|
58036
|
-
|
|
57974
|
+
client_profiler.Flush(context.thread.profiler);
|
|
58037
57975
|
}
|
|
58038
57976
|
|
|
58039
57977
|
SinkFinalizeType PhysicalNestedLoopJoin::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
@@ -58465,8 +58403,10 @@ SinkResultType PhysicalPiecewiseMergeJoin::Sink(ExecutionContext &context, Globa
|
|
|
58465
58403
|
void PhysicalPiecewiseMergeJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate,
|
|
58466
58404
|
LocalSinkState &lstate) const {
|
|
58467
58405
|
auto &state = (MergeJoinLocalState &)lstate;
|
|
58406
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
58407
|
+
|
|
58468
58408
|
context.thread.profiler.Flush(this, &state.rhs_executor, "rhs_executor", 1);
|
|
58469
|
-
|
|
58409
|
+
client_profiler.Flush(context.thread.profiler);
|
|
58470
58410
|
}
|
|
58471
58411
|
|
|
58472
58412
|
//===--------------------------------------------------------------------===//
|
|
@@ -59051,12 +58991,13 @@ public:
|
|
|
59051
58991
|
: ExecutorTask(context), event(move(event_p)), context(context), state(state) {
|
|
59052
58992
|
}
|
|
59053
58993
|
|
|
59054
|
-
|
|
58994
|
+
TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override {
|
|
59055
58995
|
// Initialize merge sorted and iterate until done
|
|
59056
58996
|
auto &global_sort_state = state.global_sort_state;
|
|
59057
58997
|
MergeSorter merge_sorter(global_sort_state, BufferManager::GetBufferManager(context));
|
|
59058
58998
|
merge_sorter.PerformInMergeRound();
|
|
59059
58999
|
event->FinishTask();
|
|
59000
|
+
return TaskExecutionResult::TASK_FINISHED;
|
|
59060
59001
|
}
|
|
59061
59002
|
|
|
59062
59003
|
private:
|
|
@@ -62392,8 +62333,9 @@ unique_ptr<LocalSinkState> PhysicalInsert::GetLocalSinkState(ExecutionContext &c
|
|
|
62392
62333
|
|
|
62393
62334
|
void PhysicalInsert::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
62394
62335
|
auto &state = (InsertLocalState &)lstate;
|
|
62336
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
62395
62337
|
context.thread.profiler.Flush(this, &state.default_executor, "default_executor", 1);
|
|
62396
|
-
|
|
62338
|
+
client_profiler.Flush(context.thread.profiler);
|
|
62397
62339
|
}
|
|
62398
62340
|
|
|
62399
62341
|
//===--------------------------------------------------------------------===//
|
|
@@ -62599,8 +62541,9 @@ unique_ptr<LocalSinkState> PhysicalUpdate::GetLocalSinkState(ExecutionContext &c
|
|
|
62599
62541
|
|
|
62600
62542
|
void PhysicalUpdate::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const {
|
|
62601
62543
|
auto &state = (UpdateLocalState &)lstate;
|
|
62544
|
+
auto &client_profiler = QueryProfiler::Get(context.client);
|
|
62602
62545
|
context.thread.profiler.Flush(this, &state.default_executor, "default_executor", 1);
|
|
62603
|
-
|
|
62546
|
+
client_profiler.Flush(context.thread.profiler);
|
|
62604
62547
|
}
|
|
62605
62548
|
|
|
62606
62549
|
//===--------------------------------------------------------------------===//
|
|
@@ -65567,6 +65510,7 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalChunkGet &
|
|
|
65567
65510
|
|
|
65568
65511
|
|
|
65569
65512
|
|
|
65513
|
+
|
|
65570
65514
|
namespace duckdb {
|
|
65571
65515
|
|
|
65572
65516
|
static bool CanPlanIndexJoin(Transaction &transaction, TableScanBindData *bind_data, PhysicalTableScan &scan) {
|
|
@@ -65586,6 +65530,30 @@ static bool CanPlanIndexJoin(Transaction &transaction, TableScanBindData *bind_d
|
|
|
65586
65530
|
return true;
|
|
65587
65531
|
}
|
|
65588
65532
|
|
|
65533
|
+
bool ExtractNumericValue(Value val, int64_t &result) {
|
|
65534
|
+
if (!val.type().IsIntegral()) {
|
|
65535
|
+
switch (val.type().InternalType()) {
|
|
65536
|
+
case PhysicalType::INT16:
|
|
65537
|
+
result = val.GetValueUnsafe<int16_t>();
|
|
65538
|
+
break;
|
|
65539
|
+
case PhysicalType::INT32:
|
|
65540
|
+
result = val.GetValueUnsafe<int32_t>();
|
|
65541
|
+
break;
|
|
65542
|
+
case PhysicalType::INT64:
|
|
65543
|
+
result = val.GetValueUnsafe<int64_t>();
|
|
65544
|
+
break;
|
|
65545
|
+
default:
|
|
65546
|
+
return false;
|
|
65547
|
+
}
|
|
65548
|
+
} else {
|
|
65549
|
+
if (!val.TryCastAs(LogicalType::BIGINT)) {
|
|
65550
|
+
return false;
|
|
65551
|
+
}
|
|
65552
|
+
result = val.GetValue<int64_t>();
|
|
65553
|
+
}
|
|
65554
|
+
return true;
|
|
65555
|
+
}
|
|
65556
|
+
|
|
65589
65557
|
void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &join_state) {
|
|
65590
65558
|
// we only do this optimization for inner joins
|
|
65591
65559
|
if (op.join_type != JoinType::INNER) {
|
|
@@ -65618,7 +65586,14 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
|
|
|
65618
65586
|
if (stats_build->min.is_null || stats_build->max.is_null) {
|
|
65619
65587
|
return;
|
|
65620
65588
|
}
|
|
65621
|
-
|
|
65589
|
+
int64_t min_value, max_value;
|
|
65590
|
+
if (!ExtractNumericValue(stats_build->min, min_value) || !ExtractNumericValue(stats_build->max, max_value)) {
|
|
65591
|
+
return;
|
|
65592
|
+
}
|
|
65593
|
+
int64_t build_range;
|
|
65594
|
+
if (!TrySubtractOperator::Operation(max_value, min_value, build_range)) {
|
|
65595
|
+
return;
|
|
65596
|
+
}
|
|
65622
65597
|
|
|
65623
65598
|
// Fill join_stats for invisible join
|
|
65624
65599
|
auto stats_probe = reinterpret_cast<NumericStatistics *>(op.join_stats[1].get()); // rhs stats
|
|
@@ -65630,26 +65605,7 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
|
|
|
65630
65605
|
join_state.build_min = stats_build->min;
|
|
65631
65606
|
join_state.build_max = stats_build->max;
|
|
65632
65607
|
join_state.estimated_cardinality = op.estimated_cardinality;
|
|
65633
|
-
|
|
65634
|
-
switch (build_range.type().InternalType()) {
|
|
65635
|
-
case PhysicalType::INT16:
|
|
65636
|
-
join_state.build_range = build_range.value_.smallint;
|
|
65637
|
-
break;
|
|
65638
|
-
case PhysicalType::INT32:
|
|
65639
|
-
join_state.build_range = build_range.value_.integer;
|
|
65640
|
-
break;
|
|
65641
|
-
case PhysicalType::INT64:
|
|
65642
|
-
join_state.build_range = build_range.value_.bigint;
|
|
65643
|
-
break;
|
|
65644
|
-
case PhysicalType::INT128:
|
|
65645
|
-
// we do not support hugeint for this optimization
|
|
65646
|
-
return;
|
|
65647
|
-
default:
|
|
65648
|
-
throw InternalException("Invalid Physical Type for Decimals");
|
|
65649
|
-
}
|
|
65650
|
-
} else {
|
|
65651
|
-
join_state.build_range = build_range.GetValue<idx_t>(); // cast integer types into idx_t
|
|
65652
|
-
}
|
|
65608
|
+
join_state.build_range = build_range;
|
|
65653
65609
|
if (join_state.build_range > MAX_BUILD_SIZE || stats_probe->max.is_null || stats_probe->min.is_null) {
|
|
65654
65610
|
return;
|
|
65655
65611
|
}
|
|
@@ -68596,25 +68552,27 @@ private:
|
|
|
68596
68552
|
};
|
|
68597
68553
|
|
|
68598
68554
|
unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(unique_ptr<LogicalOperator> op) {
|
|
68555
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
68556
|
+
|
|
68599
68557
|
// first resolve column references
|
|
68600
|
-
|
|
68558
|
+
profiler.StartPhase("column_binding");
|
|
68601
68559
|
ColumnBindingResolver resolver;
|
|
68602
68560
|
resolver.VisitOperator(*op);
|
|
68603
|
-
|
|
68561
|
+
profiler.EndPhase();
|
|
68604
68562
|
|
|
68605
68563
|
// now resolve types of all the operators
|
|
68606
|
-
|
|
68564
|
+
profiler.StartPhase("resolve_types");
|
|
68607
68565
|
op->ResolveOperatorTypes();
|
|
68608
|
-
|
|
68566
|
+
profiler.EndPhase();
|
|
68609
68567
|
|
|
68610
68568
|
// extract dependencies from the logical plan
|
|
68611
68569
|
DependencyExtractor extractor(dependencies);
|
|
68612
68570
|
extractor.VisitOperator(*op);
|
|
68613
68571
|
|
|
68614
68572
|
// then create the main physical plan
|
|
68615
|
-
|
|
68573
|
+
profiler.StartPhase("create_plan");
|
|
68616
68574
|
auto plan = CreatePlan(*op);
|
|
68617
|
-
|
|
68575
|
+
profiler.EndPhase();
|
|
68618
68576
|
return plan;
|
|
68619
68577
|
}
|
|
68620
68578
|
|
|
@@ -68976,6 +68934,7 @@ public:
|
|
|
68976
68934
|
idx_t radix_p)
|
|
68977
68935
|
: ExecutorTask(executor), event(move(event_p)), state(state_p), radix(radix_p) {
|
|
68978
68936
|
}
|
|
68937
|
+
|
|
68979
68938
|
static void FinalizeHT(RadixHTGlobalState &gstate, idx_t radix) {
|
|
68980
68939
|
D_ASSERT(gstate.partition_info.n_partitions <= gstate.finalized_hts.size());
|
|
68981
68940
|
D_ASSERT(gstate.finalized_hts[radix]);
|
|
@@ -68988,9 +68947,10 @@ public:
|
|
|
68988
68947
|
gstate.finalized_hts[radix]->Finalize();
|
|
68989
68948
|
}
|
|
68990
68949
|
|
|
68991
|
-
|
|
68950
|
+
TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override {
|
|
68992
68951
|
FinalizeHT(state, radix);
|
|
68993
68952
|
event->FinishTask();
|
|
68953
|
+
return TaskExecutionResult::TASK_FINISHED;
|
|
68994
68954
|
}
|
|
68995
68955
|
|
|
68996
68956
|
private:
|
|
@@ -77592,6 +77552,7 @@ void BuiltinFunctions::Initialize() {
|
|
|
77592
77552
|
RegisterRegressiveAggregates();
|
|
77593
77553
|
|
|
77594
77554
|
RegisterDateFunctions();
|
|
77555
|
+
RegisterEnumFunctions();
|
|
77595
77556
|
RegisterGenericFunctions();
|
|
77596
77557
|
RegisterMathFunctions();
|
|
77597
77558
|
RegisterOperators();
|
|
@@ -78092,8 +78053,9 @@ struct PragmaFunctions {
|
|
|
78092
78053
|
namespace duckdb {
|
|
78093
78054
|
|
|
78094
78055
|
static void PragmaEnableProfilingStatement(ClientContext &context, const FunctionParameters ¶meters) {
|
|
78095
|
-
|
|
78096
|
-
|
|
78056
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
78057
|
+
config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE;
|
|
78058
|
+
config.enable_profiler = true;
|
|
78097
78059
|
}
|
|
78098
78060
|
|
|
78099
78061
|
void RegisterEnableProfiling(BuiltinFunctions &set) {
|
|
@@ -78105,8 +78067,9 @@ void RegisterEnableProfiling(BuiltinFunctions &set) {
|
|
|
78105
78067
|
}
|
|
78106
78068
|
|
|
78107
78069
|
static void PragmaDisableProfiling(ClientContext &context, const FunctionParameters ¶meters) {
|
|
78108
|
-
context
|
|
78109
|
-
|
|
78070
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
78071
|
+
config.enable_profiler = false;
|
|
78072
|
+
config.profiler_print_format = ProfilerPrintFormat::NONE;
|
|
78110
78073
|
}
|
|
78111
78074
|
|
|
78112
78075
|
static void PragmaEnableProgressBar(ClientContext &context, const FunctionParameters ¶meters) {
|
|
@@ -82094,6 +82057,163 @@ void BuiltinFunctions::RegisterDateFunctions() {
|
|
|
82094
82057
|
Register<ToIntervalFun>();
|
|
82095
82058
|
}
|
|
82096
82059
|
|
|
82060
|
+
} // namespace duckdb
|
|
82061
|
+
//===----------------------------------------------------------------------===//
|
|
82062
|
+
// DuckDB
|
|
82063
|
+
//
|
|
82064
|
+
// duckdb/function/scalar/enum_functions.hpp
|
|
82065
|
+
//
|
|
82066
|
+
//
|
|
82067
|
+
//===----------------------------------------------------------------------===//
|
|
82068
|
+
|
|
82069
|
+
|
|
82070
|
+
|
|
82071
|
+
|
|
82072
|
+
|
|
82073
|
+
|
|
82074
|
+
namespace duckdb {
|
|
82075
|
+
|
|
82076
|
+
struct EnumFirst {
|
|
82077
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
82078
|
+
};
|
|
82079
|
+
|
|
82080
|
+
struct EnumLast {
|
|
82081
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
82082
|
+
};
|
|
82083
|
+
|
|
82084
|
+
struct EnumRange {
|
|
82085
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
82086
|
+
};
|
|
82087
|
+
|
|
82088
|
+
struct EnumRangeBoundary {
|
|
82089
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
82090
|
+
};
|
|
82091
|
+
|
|
82092
|
+
} // namespace duckdb
|
|
82093
|
+
|
|
82094
|
+
|
|
82095
|
+
namespace duckdb {
|
|
82096
|
+
|
|
82097
|
+
static void EnumFirstFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
82098
|
+
D_ASSERT(input.GetTypes().size() == 1);
|
|
82099
|
+
auto &enum_vector = EnumType::GetValuesInsertOrder(input.GetTypes()[0]);
|
|
82100
|
+
auto val = Value(enum_vector.GetValue(0));
|
|
82101
|
+
result.Reference(val);
|
|
82102
|
+
}
|
|
82103
|
+
|
|
82104
|
+
static void EnumLastFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
82105
|
+
D_ASSERT(input.GetTypes().size() == 1);
|
|
82106
|
+
auto enum_size = EnumType::GetSize(input.GetTypes()[0]);
|
|
82107
|
+
auto &enum_vector = EnumType::GetValuesInsertOrder(input.GetTypes()[0]);
|
|
82108
|
+
auto val = Value(enum_vector.GetValue(enum_size - 1));
|
|
82109
|
+
result.Reference(val);
|
|
82110
|
+
}
|
|
82111
|
+
|
|
82112
|
+
static void EnumRangeFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
82113
|
+
D_ASSERT(input.GetTypes().size() == 1);
|
|
82114
|
+
auto enum_size = EnumType::GetSize(input.GetTypes()[0]);
|
|
82115
|
+
auto &enum_vector = EnumType::GetValuesInsertOrder(input.GetTypes()[0]);
|
|
82116
|
+
vector<Value> enum_values;
|
|
82117
|
+
for (idx_t i = 0; i < enum_size; i++) {
|
|
82118
|
+
enum_values.emplace_back(enum_vector.GetValue(i));
|
|
82119
|
+
}
|
|
82120
|
+
auto val = Value::LIST(enum_values);
|
|
82121
|
+
result.Reference(val);
|
|
82122
|
+
}
|
|
82123
|
+
|
|
82124
|
+
static void EnumRangeBoundaryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
82125
|
+
D_ASSERT(input.GetTypes().size() == 2);
|
|
82126
|
+
idx_t start, end;
|
|
82127
|
+
auto first_param = input.GetValue(0, 0);
|
|
82128
|
+
auto second_param = input.GetValue(1, 0);
|
|
82129
|
+
|
|
82130
|
+
auto &enum_vector = first_param.is_null ? EnumType::GetValuesInsertOrder(input.GetTypes()[1])
|
|
82131
|
+
: EnumType::GetValuesInsertOrder(input.GetTypes()[0]);
|
|
82132
|
+
|
|
82133
|
+
if (first_param.is_null) {
|
|
82134
|
+
start = 0;
|
|
82135
|
+
} else {
|
|
82136
|
+
start = first_param.GetValue<uint32_t>();
|
|
82137
|
+
}
|
|
82138
|
+
if (second_param.is_null) {
|
|
82139
|
+
end = EnumType::GetSize(input.GetTypes()[0]);
|
|
82140
|
+
} else {
|
|
82141
|
+
end = second_param.GetValue<uint32_t>() + 1;
|
|
82142
|
+
}
|
|
82143
|
+
vector<Value> enum_values;
|
|
82144
|
+
for (idx_t i = start; i < end; i++) {
|
|
82145
|
+
enum_values.emplace_back(enum_vector.GetValue(i));
|
|
82146
|
+
}
|
|
82147
|
+
Value val;
|
|
82148
|
+
if (enum_values.empty()) {
|
|
82149
|
+
val = Value::EMPTYLIST(LogicalType::VARCHAR);
|
|
82150
|
+
} else {
|
|
82151
|
+
val = Value::LIST(enum_values);
|
|
82152
|
+
}
|
|
82153
|
+
result.Reference(val);
|
|
82154
|
+
}
|
|
82155
|
+
|
|
82156
|
+
unique_ptr<FunctionData> BindEnumFunction(ClientContext &context, ScalarFunction &bound_function,
|
|
82157
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
82158
|
+
if (arguments[0]->return_type.id() != LogicalTypeId::ENUM) {
|
|
82159
|
+
throw BinderException("This function needs an ENUM as an argument");
|
|
82160
|
+
}
|
|
82161
|
+
return nullptr;
|
|
82162
|
+
}
|
|
82163
|
+
|
|
82164
|
+
unique_ptr<FunctionData> BindEnumRangeBoundaryFunction(ClientContext &context, ScalarFunction &bound_function,
|
|
82165
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
82166
|
+
if (arguments[0]->return_type.id() != LogicalTypeId::ENUM && arguments[0]->return_type != LogicalType::SQLNULL) {
|
|
82167
|
+
throw BinderException("This function needs an ENUM as an argument");
|
|
82168
|
+
}
|
|
82169
|
+
if (arguments[1]->return_type.id() != LogicalTypeId::ENUM && arguments[1]->return_type != LogicalType::SQLNULL) {
|
|
82170
|
+
throw BinderException("This function needs an ENUM as an argument");
|
|
82171
|
+
}
|
|
82172
|
+
if (arguments[0]->return_type == LogicalType::SQLNULL && arguments[1]->return_type == LogicalType::SQLNULL) {
|
|
82173
|
+
throw BinderException("This function needs an ENUM as an argument");
|
|
82174
|
+
}
|
|
82175
|
+
if (arguments[0]->return_type.id() == LogicalTypeId::ENUM &&
|
|
82176
|
+
arguments[1]->return_type.id() == LogicalTypeId::ENUM &&
|
|
82177
|
+
arguments[0]->return_type != arguments[1]->return_type) {
|
|
82178
|
+
|
|
82179
|
+
throw BinderException("The parameters need to link to ONLY one enum OR be NULL ");
|
|
82180
|
+
}
|
|
82181
|
+
return nullptr;
|
|
82182
|
+
}
|
|
82183
|
+
|
|
82184
|
+
void EnumFirst::RegisterFunction(BuiltinFunctions &set) {
|
|
82185
|
+
set.AddFunction(ScalarFunction("enum_first", {LogicalType::ANY}, LogicalType::VARCHAR, EnumFirstFunction, false,
|
|
82186
|
+
BindEnumFunction));
|
|
82187
|
+
}
|
|
82188
|
+
|
|
82189
|
+
void EnumLast::RegisterFunction(BuiltinFunctions &set) {
|
|
82190
|
+
set.AddFunction(ScalarFunction("enum_last", {LogicalType::ANY}, LogicalType::VARCHAR, EnumLastFunction, false,
|
|
82191
|
+
BindEnumFunction));
|
|
82192
|
+
}
|
|
82193
|
+
|
|
82194
|
+
void EnumRange::RegisterFunction(BuiltinFunctions &set) {
|
|
82195
|
+
set.AddFunction(ScalarFunction("enum_range", {LogicalType::ANY}, LogicalType::LIST(LogicalType::VARCHAR),
|
|
82196
|
+
EnumRangeFunction, false, BindEnumFunction));
|
|
82197
|
+
}
|
|
82198
|
+
|
|
82199
|
+
void EnumRangeBoundary::RegisterFunction(BuiltinFunctions &set) {
|
|
82200
|
+
set.AddFunction(ScalarFunction("enum_range_boundary", {LogicalType::ANY, LogicalType::ANY},
|
|
82201
|
+
LogicalType::LIST(LogicalType::VARCHAR), EnumRangeBoundaryFunction, false,
|
|
82202
|
+
BindEnumRangeBoundaryFunction));
|
|
82203
|
+
}
|
|
82204
|
+
|
|
82205
|
+
} // namespace duckdb
|
|
82206
|
+
|
|
82207
|
+
|
|
82208
|
+
namespace duckdb {
|
|
82209
|
+
|
|
82210
|
+
void BuiltinFunctions::RegisterEnumFunctions() {
|
|
82211
|
+
Register<EnumFirst>();
|
|
82212
|
+
Register<EnumLast>();
|
|
82213
|
+
Register<EnumRange>();
|
|
82214
|
+
Register<EnumRangeBoundary>();
|
|
82215
|
+
}
|
|
82216
|
+
|
|
82097
82217
|
} // namespace duckdb
|
|
82098
82218
|
//===----------------------------------------------------------------------===//
|
|
82099
82219
|
// DuckDB
|
|
@@ -91738,8 +91858,7 @@ unique_ptr<FunctionData> BindSystemFunction(ClientContext &context, ScalarFuncti
|
|
|
91738
91858
|
|
|
91739
91859
|
static void CurrentQueryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
91740
91860
|
auto &info = SystemBindData::GetFrom(state);
|
|
91741
|
-
|
|
91742
|
-
Value val(info.context.query);
|
|
91861
|
+
Value val(info.context.GetCurrentQuery());
|
|
91743
91862
|
result.Reference(val);
|
|
91744
91863
|
}
|
|
91745
91864
|
|
|
@@ -91981,6 +92100,21 @@ void ScalarFunction::NopFunction(DataChunk &input, ExpressionState &state, Vecto
|
|
|
91981
92100
|
|
|
91982
92101
|
|
|
91983
92102
|
|
|
92103
|
+
//===----------------------------------------------------------------------===//
|
|
92104
|
+
// DuckDB
|
|
92105
|
+
//
|
|
92106
|
+
// duckdb/common/thread.hpp
|
|
92107
|
+
//
|
|
92108
|
+
//
|
|
92109
|
+
//===----------------------------------------------------------------------===//
|
|
92110
|
+
|
|
92111
|
+
|
|
92112
|
+
|
|
92113
|
+
#include <thread>
|
|
92114
|
+
|
|
92115
|
+
namespace duckdb {
|
|
92116
|
+
using std::thread;
|
|
92117
|
+
}
|
|
91984
92118
|
|
|
91985
92119
|
#include <map>
|
|
91986
92120
|
#include <condition_variable>
|
|
@@ -92126,7 +92260,7 @@ private:
|
|
|
92126
92260
|
//! Gets Arrow Table's Cardinality
|
|
92127
92261
|
static unique_ptr<NodeStatistics> ArrowScanCardinality(ClientContext &context, const FunctionData *bind_data);
|
|
92128
92262
|
//! Gets the progress on the table scan, used for Progress Bars
|
|
92129
|
-
static
|
|
92263
|
+
static double ArrowProgress(ClientContext &context, const FunctionData *bind_data_p);
|
|
92130
92264
|
};
|
|
92131
92265
|
|
|
92132
92266
|
} // namespace duckdb
|
|
@@ -93225,12 +93359,12 @@ unique_ptr<NodeStatistics> ArrowTableFunction::ArrowScanCardinality(ClientContex
|
|
|
93225
93359
|
return make_unique<NodeStatistics>(bind_data.number_of_rows, bind_data.number_of_rows);
|
|
93226
93360
|
}
|
|
93227
93361
|
|
|
93228
|
-
|
|
93362
|
+
double ArrowTableFunction::ArrowProgress(ClientContext &context, const FunctionData *bind_data_p) {
|
|
93229
93363
|
auto &bind_data = (const ArrowScanFunctionData &)*bind_data_p;
|
|
93230
93364
|
if (bind_data.number_of_rows == 0) {
|
|
93231
93365
|
return 100;
|
|
93232
93366
|
}
|
|
93233
|
-
auto percentage = bind_data.lines_read * 100 / bind_data.number_of_rows;
|
|
93367
|
+
auto percentage = bind_data.lines_read * 100.0 / bind_data.number_of_rows;
|
|
93234
93368
|
return percentage;
|
|
93235
93369
|
}
|
|
93236
93370
|
|
|
@@ -94915,12 +95049,12 @@ static void ReadCSVAddNamedParameters(TableFunction &table_function) {
|
|
|
94915
95049
|
table_function.named_parameters["skip"] = LogicalType::BIGINT;
|
|
94916
95050
|
}
|
|
94917
95051
|
|
|
94918
|
-
|
|
95052
|
+
double CSVReaderProgress(ClientContext &context, const FunctionData *bind_data_p) {
|
|
94919
95053
|
auto &bind_data = (ReadCSVData &)*bind_data_p;
|
|
94920
95054
|
if (bind_data.file_size == 0) {
|
|
94921
95055
|
return 100;
|
|
94922
95056
|
}
|
|
94923
|
-
auto percentage = bind_data.bytes_read * 100 / bind_data.file_size;
|
|
95057
|
+
auto percentage = (bind_data.bytes_read * 100.0) / bind_data.file_size;
|
|
94924
95058
|
return percentage;
|
|
94925
95059
|
}
|
|
94926
95060
|
|
|
@@ -98134,14 +98268,14 @@ bool TableScanParallelStateNext(ClientContext &context, const FunctionData *bind
|
|
|
98134
98268
|
state.column_ids);
|
|
98135
98269
|
}
|
|
98136
98270
|
|
|
98137
|
-
|
|
98271
|
+
double TableScanProgress(ClientContext &context, const FunctionData *bind_data_p) {
|
|
98138
98272
|
auto &bind_data = (TableScanBindData &)*bind_data_p;
|
|
98139
98273
|
idx_t total_rows = bind_data.table->storage->GetTotalRows();
|
|
98140
98274
|
if (total_rows == 0 || total_rows < STANDARD_VECTOR_SIZE) {
|
|
98141
98275
|
//! Table is either empty or smaller than a vector size, so it is finished
|
|
98142
98276
|
return 100;
|
|
98143
98277
|
}
|
|
98144
|
-
auto percentage = (bind_data.chunk_count * STANDARD_VECTOR_SIZE * 100) / total_rows;
|
|
98278
|
+
auto percentage = double(bind_data.chunk_count * STANDARD_VECTOR_SIZE * 100.0) / total_rows;
|
|
98145
98279
|
if (percentage > 100) {
|
|
98146
98280
|
//! In case the last chunk has less elements than STANDARD_VECTOR_SIZE, if our percentage is over 100
|
|
98147
98281
|
//! It means we finished this table.
|
|
@@ -100877,28 +101011,27 @@ private:
|
|
|
100877
101011
|
|
|
100878
101012
|
namespace duckdb {
|
|
100879
101013
|
|
|
100880
|
-
|
|
100881
|
-
|
|
100882
|
-
|
|
100883
|
-
|
|
100884
|
-
|
|
100885
|
-
|
|
100886
|
-
|
|
100887
|
-
|
|
100888
|
-
|
|
100889
|
-
|
|
101014
|
+
struct ActiveQueryContext {
|
|
101015
|
+
//! The query that is currently being executed
|
|
101016
|
+
string query;
|
|
101017
|
+
//! The currently open result
|
|
101018
|
+
BaseQueryResult *open_result = nullptr;
|
|
101019
|
+
//! Prepared statement data
|
|
101020
|
+
shared_ptr<PreparedStatementData> prepared;
|
|
101021
|
+
//! The query executor
|
|
101022
|
+
unique_ptr<Executor> executor;
|
|
101023
|
+
//! The progress bar
|
|
101024
|
+
unique_ptr<ProgressBar> progress_bar;
|
|
100890
101025
|
};
|
|
100891
101026
|
|
|
100892
101027
|
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),
|
|
101028
|
+
: profiler(make_unique<QueryProfiler>(*this)), query_profiler_history(make_unique<QueryProfilerHistory>()),
|
|
101029
|
+
db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false),
|
|
100895
101030
|
temporary_objects(make_unique<SchemaCatalogEntry>(&db->GetCatalog(), TEMP_SCHEMA, true)),
|
|
100896
101031
|
catalog_search_path(make_unique<CatalogSearchPath>(*this)),
|
|
100897
|
-
file_opener(make_unique<ClientContextFileOpener>(*this))
|
|
101032
|
+
file_opener(make_unique<ClientContextFileOpener>(*this)) {
|
|
100898
101033
|
std::random_device rd;
|
|
100899
101034
|
random_engine.seed(rd());
|
|
100900
|
-
|
|
100901
|
-
progress_bar = make_unique<ProgressBar>(&executor, config.wait_time);
|
|
100902
101035
|
}
|
|
100903
101036
|
|
|
100904
101037
|
ClientContext::~ClientContext() {
|
|
@@ -100925,87 +101058,162 @@ void ClientContext::Destroy() {
|
|
|
100925
101058
|
CleanupInternal(*lock);
|
|
100926
101059
|
}
|
|
100927
101060
|
|
|
100928
|
-
|
|
100929
|
-
|
|
100930
|
-
|
|
101061
|
+
unique_ptr<DataChunk> ClientContext::Fetch(ClientContextLock &lock, StreamQueryResult &result) {
|
|
101062
|
+
D_ASSERT(IsActiveResult(lock, &result));
|
|
101063
|
+
D_ASSERT(active_query->executor);
|
|
101064
|
+
return FetchInternal(lock, *active_query->executor, result);
|
|
100931
101065
|
}
|
|
100932
101066
|
|
|
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
|
-
}
|
|
101067
|
+
unique_ptr<DataChunk> ClientContext::FetchInternal(ClientContextLock &lock, Executor &executor,
|
|
101068
|
+
BaseQueryResult &result) {
|
|
101069
|
+
bool invalidate_query = true;
|
|
100938
101070
|
try {
|
|
100939
101071
|
// fetch the chunk and return it
|
|
100940
|
-
auto chunk =
|
|
101072
|
+
auto chunk = executor.FetchChunk();
|
|
101073
|
+
if (!chunk || chunk->size() == 0) {
|
|
101074
|
+
CleanupInternal(lock, &result);
|
|
101075
|
+
}
|
|
100941
101076
|
return chunk;
|
|
101077
|
+
} catch (StandardException &ex) {
|
|
101078
|
+
// standard exceptions do not invalidate the current transaction
|
|
101079
|
+
result.error = ex.what();
|
|
101080
|
+
invalidate_query = false;
|
|
100942
101081
|
} catch (std::exception &ex) {
|
|
100943
|
-
|
|
101082
|
+
result.error = ex.what();
|
|
100944
101083
|
} catch (...) { // LCOV_EXCL_START
|
|
100945
|
-
|
|
101084
|
+
result.error = "Unhandled exception in FetchInternal";
|
|
100946
101085
|
} // LCOV_EXCL_STOP
|
|
100947
|
-
|
|
100948
|
-
CleanupInternal(
|
|
101086
|
+
result.success = false;
|
|
101087
|
+
CleanupInternal(lock, &result, invalidate_query);
|
|
100949
101088
|
return nullptr;
|
|
100950
101089
|
}
|
|
100951
101090
|
|
|
100952
|
-
|
|
101091
|
+
void ClientContext::BeginTransactionInternal(ClientContextLock &lock, bool requires_valid_transaction) {
|
|
101092
|
+
// check if we are on AutoCommit. In this case we should start a transaction
|
|
101093
|
+
D_ASSERT(!active_query);
|
|
101094
|
+
if (requires_valid_transaction && transaction.HasActiveTransaction() &&
|
|
101095
|
+
transaction.ActiveTransaction().IsInvalidated()) {
|
|
101096
|
+
throw Exception("Failed: transaction has been invalidated!");
|
|
101097
|
+
}
|
|
101098
|
+
active_query = make_unique<ActiveQueryContext>();
|
|
101099
|
+
if (transaction.IsAutoCommit()) {
|
|
101100
|
+
transaction.BeginTransaction();
|
|
101101
|
+
}
|
|
101102
|
+
}
|
|
101103
|
+
|
|
101104
|
+
void ClientContext::BeginQueryInternal(ClientContextLock &lock, const string &query) {
|
|
101105
|
+
BeginTransactionInternal(lock, false);
|
|
101106
|
+
LogQueryInternal(lock, query);
|
|
101107
|
+
active_query->query = query;
|
|
101108
|
+
query_progress = -1;
|
|
101109
|
+
ActiveTransaction().active_query = db->GetTransactionManager().GetQueryNumber();
|
|
101110
|
+
}
|
|
101111
|
+
|
|
101112
|
+
string ClientContext::EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction) {
|
|
100953
101113
|
profiler->EndQuery();
|
|
100954
|
-
executor.Reset();
|
|
100955
101114
|
|
|
101115
|
+
D_ASSERT(active_query.get());
|
|
100956
101116
|
string error;
|
|
100957
|
-
|
|
100958
|
-
|
|
100959
|
-
|
|
100960
|
-
|
|
100961
|
-
|
|
100962
|
-
|
|
100963
|
-
|
|
100964
|
-
|
|
100965
|
-
|
|
100966
|
-
|
|
100967
|
-
|
|
100968
|
-
|
|
100969
|
-
|
|
101117
|
+
try {
|
|
101118
|
+
if (transaction.HasActiveTransaction()) {
|
|
101119
|
+
// Move the query profiler into the history
|
|
101120
|
+
auto &prev_profilers = query_profiler_history->GetPrevProfilers();
|
|
101121
|
+
prev_profilers.emplace_back(transaction.ActiveTransaction().active_query, move(profiler));
|
|
101122
|
+
// Reinitialize the query profiler
|
|
101123
|
+
profiler = make_unique<QueryProfiler>(*this);
|
|
101124
|
+
// Propagate settings of the saved query into the new profiler.
|
|
101125
|
+
profiler->Propagate(*prev_profilers.back().second);
|
|
101126
|
+
if (prev_profilers.size() >= query_profiler_history->GetPrevProfilersSize()) {
|
|
101127
|
+
prev_profilers.pop_front();
|
|
101128
|
+
}
|
|
101129
|
+
|
|
101130
|
+
ActiveTransaction().active_query = MAXIMUM_QUERY_ID;
|
|
100970
101131
|
if (transaction.IsAutoCommit()) {
|
|
100971
101132
|
if (success) {
|
|
100972
|
-
// query was successful: commit
|
|
100973
101133
|
transaction.Commit();
|
|
100974
101134
|
} else {
|
|
100975
|
-
// query was unsuccessful: rollback
|
|
100976
101135
|
transaction.Rollback();
|
|
100977
101136
|
}
|
|
101137
|
+
} else if (invalidate_transaction) {
|
|
101138
|
+
D_ASSERT(!success);
|
|
101139
|
+
ActiveTransaction().Invalidate();
|
|
100978
101140
|
}
|
|
100979
|
-
}
|
|
100980
|
-
|
|
100981
|
-
|
|
100982
|
-
|
|
100983
|
-
|
|
100984
|
-
}
|
|
101141
|
+
}
|
|
101142
|
+
} catch (std::exception &ex) {
|
|
101143
|
+
error = ex.what();
|
|
101144
|
+
} catch (...) { // LCOV_EXCL_START
|
|
101145
|
+
error = "Unhandled exception!";
|
|
101146
|
+
} // LCOV_EXCL_STOP
|
|
101147
|
+
active_query.reset();
|
|
101148
|
+
query_progress = -1;
|
|
100985
101149
|
return error;
|
|
100986
101150
|
}
|
|
100987
101151
|
|
|
100988
|
-
void ClientContext::CleanupInternal(ClientContextLock &lock) {
|
|
100989
|
-
if (!
|
|
100990
|
-
// no
|
|
101152
|
+
void ClientContext::CleanupInternal(ClientContextLock &lock, BaseQueryResult *result, bool invalidate_transaction) {
|
|
101153
|
+
if (!active_query) {
|
|
101154
|
+
// no query currently active
|
|
100991
101155
|
return;
|
|
100992
101156
|
}
|
|
101157
|
+
if (active_query->executor) {
|
|
101158
|
+
active_query->executor->CancelTasks();
|
|
101159
|
+
}
|
|
101160
|
+
active_query->progress_bar.reset();
|
|
100993
101161
|
|
|
100994
|
-
auto error =
|
|
100995
|
-
if (
|
|
101162
|
+
auto error = EndQueryInternal(lock, result ? result->success : false, invalidate_transaction);
|
|
101163
|
+
if (result && result->success) {
|
|
100996
101164
|
// if an error occurred while committing report it in the result
|
|
100997
|
-
|
|
100998
|
-
|
|
101165
|
+
result->error = error;
|
|
101166
|
+
result->success = error.empty();
|
|
100999
101167
|
}
|
|
101168
|
+
D_ASSERT(!active_query);
|
|
101169
|
+
}
|
|
101000
101170
|
|
|
101001
|
-
|
|
101002
|
-
|
|
101171
|
+
Executor &ClientContext::GetExecutor() {
|
|
101172
|
+
D_ASSERT(active_query);
|
|
101173
|
+
D_ASSERT(active_query->executor);
|
|
101174
|
+
return *active_query->executor;
|
|
101175
|
+
}
|
|
101003
101176
|
|
|
101004
|
-
|
|
101177
|
+
const string &ClientContext::GetCurrentQuery() {
|
|
101178
|
+
D_ASSERT(active_query);
|
|
101179
|
+
return active_query->query;
|
|
101005
101180
|
}
|
|
101006
101181
|
|
|
101007
|
-
unique_ptr<
|
|
101008
|
-
|
|
101182
|
+
unique_ptr<QueryResult> ClientContext::FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending,
|
|
101183
|
+
bool allow_stream_result) {
|
|
101184
|
+
D_ASSERT(active_query);
|
|
101185
|
+
D_ASSERT(active_query->open_result == &pending);
|
|
101186
|
+
D_ASSERT(active_query->prepared);
|
|
101187
|
+
auto &prepared = *active_query->prepared;
|
|
101188
|
+
bool create_stream_result = prepared.allow_stream_result && allow_stream_result;
|
|
101189
|
+
if (create_stream_result) {
|
|
101190
|
+
active_query->progress_bar.reset();
|
|
101191
|
+
query_progress = -1;
|
|
101192
|
+
|
|
101193
|
+
// successfully compiled SELECT clause and it is the last statement
|
|
101194
|
+
// return a StreamQueryResult so the client can call Fetch() on it and stream the result
|
|
101195
|
+
auto stream_result =
|
|
101196
|
+
make_unique<StreamQueryResult>(pending.statement_type, shared_from_this(), pending.types, pending.names);
|
|
101197
|
+
active_query->open_result = stream_result.get();
|
|
101198
|
+
return move(stream_result);
|
|
101199
|
+
}
|
|
101200
|
+
// create a materialized result by continuously fetching
|
|
101201
|
+
auto result = make_unique<MaterializedQueryResult>(pending.statement_type, pending.types, pending.names);
|
|
101202
|
+
while (true) {
|
|
101203
|
+
auto chunk = FetchInternal(lock, GetExecutor(), *result);
|
|
101204
|
+
if (!chunk || chunk->size() == 0) {
|
|
101205
|
+
break;
|
|
101206
|
+
}
|
|
101207
|
+
#ifdef DEBUG
|
|
101208
|
+
for (idx_t i = 0; i < chunk->ColumnCount(); i++) {
|
|
101209
|
+
if (pending.types[i].id() == LogicalTypeId::VARCHAR) {
|
|
101210
|
+
chunk->data[i].UTFVerify(chunk->size());
|
|
101211
|
+
}
|
|
101212
|
+
}
|
|
101213
|
+
#endif
|
|
101214
|
+
result->collection.Append(*chunk);
|
|
101215
|
+
}
|
|
101216
|
+
return move(result);
|
|
101009
101217
|
}
|
|
101010
101218
|
|
|
101011
101219
|
shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientContextLock &lock, const string &query,
|
|
@@ -101013,11 +101221,12 @@ shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientC
|
|
|
101013
101221
|
StatementType statement_type = statement->type;
|
|
101014
101222
|
auto result = make_shared<PreparedStatementData>(statement_type);
|
|
101015
101223
|
|
|
101016
|
-
profiler
|
|
101224
|
+
auto &profiler = QueryProfiler::Get(*this);
|
|
101225
|
+
profiler.StartPhase("planner");
|
|
101017
101226
|
Planner planner(*this);
|
|
101018
101227
|
planner.CreatePlan(move(statement));
|
|
101019
101228
|
D_ASSERT(planner.plan);
|
|
101020
|
-
profiler
|
|
101229
|
+
profiler.EndPhase();
|
|
101021
101230
|
|
|
101022
101231
|
auto plan = move(planner.plan);
|
|
101023
101232
|
#ifdef DEBUG
|
|
@@ -101033,22 +101242,22 @@ shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientC
|
|
|
101033
101242
|
result->catalog_version = Transaction::GetTransaction(*this).catalog_version;
|
|
101034
101243
|
|
|
101035
101244
|
if (config.enable_optimizer) {
|
|
101036
|
-
profiler
|
|
101245
|
+
profiler.StartPhase("optimizer");
|
|
101037
101246
|
Optimizer optimizer(*planner.binder, *this);
|
|
101038
101247
|
plan = optimizer.Optimize(move(plan));
|
|
101039
101248
|
D_ASSERT(plan);
|
|
101040
|
-
profiler
|
|
101249
|
+
profiler.EndPhase();
|
|
101041
101250
|
|
|
101042
101251
|
#ifdef DEBUG
|
|
101043
101252
|
plan->Verify();
|
|
101044
101253
|
#endif
|
|
101045
101254
|
}
|
|
101046
101255
|
|
|
101047
|
-
profiler
|
|
101256
|
+
profiler.StartPhase("physical_planner");
|
|
101048
101257
|
// now convert logical query plan into a physical query plan
|
|
101049
101258
|
PhysicalPlanGenerator physical_planner(*this);
|
|
101050
101259
|
auto physical_plan = physical_planner.CreatePlan(move(plan));
|
|
101051
|
-
profiler
|
|
101260
|
+
profiler.EndPhase();
|
|
101052
101261
|
|
|
101053
101262
|
#ifdef DEBUG
|
|
101054
101263
|
D_ASSERT(!physical_plan->ToString().empty());
|
|
@@ -101057,14 +101266,14 @@ shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientC
|
|
|
101057
101266
|
return result;
|
|
101058
101267
|
}
|
|
101059
101268
|
|
|
101060
|
-
|
|
101061
|
-
|
|
101062
|
-
return progress_bar->GetCurrentPercentage();
|
|
101269
|
+
double ClientContext::GetProgress() {
|
|
101270
|
+
return query_progress.load();
|
|
101063
101271
|
}
|
|
101064
101272
|
|
|
101065
|
-
unique_ptr<
|
|
101066
|
-
|
|
101067
|
-
|
|
101273
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingPreparedStatement(ClientContextLock &lock,
|
|
101274
|
+
shared_ptr<PreparedStatementData> statement_p,
|
|
101275
|
+
vector<Value> bound_values) {
|
|
101276
|
+
D_ASSERT(active_query);
|
|
101068
101277
|
auto &statement = *statement_p;
|
|
101069
101278
|
if (ActiveTransaction().IsInvalidated() && statement.requires_valid_transaction) {
|
|
101070
101279
|
throw Exception("Current transaction is aborted (please ROLLBACK)");
|
|
@@ -101078,47 +101287,42 @@ unique_ptr<QueryResult> ClientContext::ExecutePreparedStatement(ClientContextLoc
|
|
|
101078
101287
|
// bind the bound values before execution
|
|
101079
101288
|
statement.Bind(move(bound_values));
|
|
101080
101289
|
|
|
101081
|
-
|
|
101290
|
+
active_query->executor = make_unique<Executor>(*this);
|
|
101291
|
+
auto &executor = *active_query->executor;
|
|
101082
101292
|
if (config.enable_progress_bar) {
|
|
101083
|
-
progress_bar
|
|
101084
|
-
progress_bar->Start();
|
|
101293
|
+
active_query->progress_bar = make_unique<ProgressBar>(executor, config.wait_time);
|
|
101294
|
+
active_query->progress_bar->Start();
|
|
101295
|
+
query_progress = 0;
|
|
101085
101296
|
}
|
|
101086
|
-
// store the physical plan in the context for calls to Fetch()
|
|
101087
101297
|
executor.Initialize(statement.plan.get());
|
|
101088
|
-
|
|
101089
101298
|
auto types = executor.GetTypes();
|
|
101090
|
-
|
|
101091
101299
|
D_ASSERT(types == statement.types);
|
|
101300
|
+
D_ASSERT(!active_query->open_result);
|
|
101092
101301
|
|
|
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
|
-
}
|
|
101302
|
+
auto pending_result = make_unique<PendingQueryResult>(shared_from_this(), *statement_p, move(types));
|
|
101303
|
+
active_query->prepared = move(statement_p);
|
|
101304
|
+
active_query->open_result = pending_result.get();
|
|
101305
|
+
return pending_result;
|
|
101306
|
+
}
|
|
101307
|
+
|
|
101308
|
+
PendingExecutionResult ClientContext::ExecuteTaskInternal(ClientContextLock &lock, PendingQueryResult &result) {
|
|
101309
|
+
D_ASSERT(active_query);
|
|
101310
|
+
D_ASSERT(active_query->open_result == &result);
|
|
101311
|
+
try {
|
|
101312
|
+
auto result = active_query->executor->ExecuteTask();
|
|
101313
|
+
if (active_query->progress_bar) {
|
|
101314
|
+
active_query->progress_bar->Update(result == PendingExecutionResult::RESULT_READY);
|
|
101315
|
+
query_progress = active_query->progress_bar->GetCurrentPercentage();
|
|
101114
101316
|
}
|
|
101115
|
-
|
|
101116
|
-
|
|
101117
|
-
|
|
101118
|
-
|
|
101119
|
-
|
|
101120
|
-
}
|
|
101121
|
-
|
|
101317
|
+
return result;
|
|
101318
|
+
} catch (std::exception &ex) {
|
|
101319
|
+
result.error = ex.what();
|
|
101320
|
+
} catch (...) { // LCOV_EXCL_START
|
|
101321
|
+
result.error = "Unhandled exception in ExecuteTaskInternal";
|
|
101322
|
+
} // LCOV_EXCL_STOP
|
|
101323
|
+
EndQueryInternal(lock, false, true);
|
|
101324
|
+
result.success = false;
|
|
101325
|
+
return PendingExecutionResult::EXECUTION_ERROR;
|
|
101122
101326
|
}
|
|
101123
101327
|
|
|
101124
101328
|
void ClientContext::InitialCleanup(ClientContextLock &lock) {
|
|
@@ -101221,27 +101425,58 @@ unique_ptr<PreparedStatement> ClientContext::Prepare(const string &query) {
|
|
|
101221
101425
|
}
|
|
101222
101426
|
}
|
|
101223
101427
|
|
|
101428
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQueryPreparedInternal(ClientContextLock &lock, const string &query,
|
|
101429
|
+
shared_ptr<PreparedStatementData> &prepared,
|
|
101430
|
+
vector<Value> &values) {
|
|
101431
|
+
try {
|
|
101432
|
+
InitialCleanup(lock);
|
|
101433
|
+
} catch (std::exception &ex) {
|
|
101434
|
+
return make_unique<PendingQueryResult>(ex.what());
|
|
101435
|
+
}
|
|
101436
|
+
return PendingStatementOrPreparedStatementInternal(lock, query, nullptr, prepared, &values);
|
|
101437
|
+
}
|
|
101438
|
+
|
|
101439
|
+
unique_ptr<PendingQueryResult>
|
|
101440
|
+
ClientContext::PendingQuery(const string &query, shared_ptr<PreparedStatementData> &prepared, vector<Value> &values) {
|
|
101441
|
+
auto lock = LockContext();
|
|
101442
|
+
return PendingQueryPreparedInternal(*lock, query, prepared, values);
|
|
101443
|
+
}
|
|
101444
|
+
|
|
101224
101445
|
unique_ptr<QueryResult> ClientContext::Execute(const string &query, shared_ptr<PreparedStatementData> &prepared,
|
|
101225
101446
|
vector<Value> &values, bool allow_stream_result) {
|
|
101226
101447
|
auto lock = LockContext();
|
|
101227
|
-
|
|
101228
|
-
|
|
101229
|
-
|
|
101230
|
-
return make_unique<MaterializedQueryResult>(ex.what());
|
|
101448
|
+
auto pending = PendingQueryPreparedInternal(*lock, query, prepared, values);
|
|
101449
|
+
if (!pending->success) {
|
|
101450
|
+
return make_unique<MaterializedQueryResult>(pending->error);
|
|
101231
101451
|
}
|
|
101232
|
-
|
|
101233
|
-
return RunStatementOrPreparedStatement(*lock, query, nullptr, prepared, &values, allow_stream_result);
|
|
101452
|
+
return pending->ExecuteInternal(*lock, allow_stream_result);
|
|
101234
101453
|
}
|
|
101235
101454
|
|
|
101236
|
-
unique_ptr<
|
|
101237
|
-
|
|
101238
|
-
bool allow_stream_result) {
|
|
101455
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingStatementInternal(ClientContextLock &lock, const string &query,
|
|
101456
|
+
unique_ptr<SQLStatement> statement) {
|
|
101239
101457
|
// prepare the query for execution
|
|
101240
101458
|
auto prepared = CreatePreparedStatement(lock, query, move(statement));
|
|
101241
101459
|
// by default, no values are bound
|
|
101242
101460
|
vector<Value> bound_values;
|
|
101243
101461
|
// execute the prepared statement
|
|
101244
|
-
return
|
|
101462
|
+
return PendingPreparedStatement(lock, move(prepared), move(bound_values));
|
|
101463
|
+
}
|
|
101464
|
+
|
|
101465
|
+
unique_ptr<QueryResult> ClientContext::RunStatementInternal(ClientContextLock &lock, const string &query,
|
|
101466
|
+
unique_ptr<SQLStatement> statement,
|
|
101467
|
+
bool allow_stream_result, bool verify) {
|
|
101468
|
+
auto pending = PendingQueryInternal(lock, move(statement), verify);
|
|
101469
|
+
if (!pending->success) {
|
|
101470
|
+
return make_unique<MaterializedQueryResult>(move(pending->error));
|
|
101471
|
+
}
|
|
101472
|
+
return ExecutePendingQueryInternal(lock, *pending, allow_stream_result);
|
|
101473
|
+
}
|
|
101474
|
+
|
|
101475
|
+
bool ClientContext::IsActiveResult(ClientContextLock &lock, BaseQueryResult *result) {
|
|
101476
|
+
if (!active_query) {
|
|
101477
|
+
return false;
|
|
101478
|
+
}
|
|
101479
|
+
return active_query->open_result == result;
|
|
101245
101480
|
}
|
|
101246
101481
|
|
|
101247
101482
|
static bool IsExplainAnalyze(SQLStatement *statement) {
|
|
@@ -101255,19 +101490,10 @@ static bool IsExplainAnalyze(SQLStatement *statement) {
|
|
|
101255
101490
|
return explain.explain_type == ExplainType::EXPLAIN_ANALYZE;
|
|
101256
101491
|
}
|
|
101257
101492
|
|
|
101258
|
-
unique_ptr<
|
|
101259
|
-
|
|
101260
|
-
|
|
101261
|
-
vector<Value> *values,
|
|
101262
|
-
bool allow_stream_result) {
|
|
101263
|
-
this->query = query;
|
|
101264
|
-
|
|
101265
|
-
unique_ptr<QueryResult> result;
|
|
101493
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingStatementOrPreparedStatementInternal(
|
|
101494
|
+
ClientContextLock &lock, const string &query, unique_ptr<SQLStatement> statement,
|
|
101495
|
+
shared_ptr<PreparedStatementData> &prepared, vector<Value> *values) {
|
|
101266
101496
|
// 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
101497
|
if (statement && config.query_verification_enabled) {
|
|
101272
101498
|
// query verification is enabled
|
|
101273
101499
|
// create a copy of the statement, and use the copy
|
|
@@ -101277,19 +101503,29 @@ unique_ptr<QueryResult> ClientContext::RunStatementOrPreparedStatement(ClientCon
|
|
|
101277
101503
|
// in case this is a select query, we verify the original statement
|
|
101278
101504
|
string error = VerifyQuery(lock, query, move(statement));
|
|
101279
101505
|
if (!error.empty()) {
|
|
101280
|
-
// query failed: abort now
|
|
101281
|
-
FinalizeQuery(lock, false);
|
|
101282
101506
|
// error in verifying query
|
|
101283
|
-
return make_unique<
|
|
101507
|
+
return make_unique<PendingQueryResult>(error);
|
|
101284
101508
|
}
|
|
101285
101509
|
}
|
|
101286
101510
|
statement = move(copied_statement);
|
|
101287
101511
|
}
|
|
101512
|
+
return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, values);
|
|
101513
|
+
}
|
|
101514
|
+
|
|
101515
|
+
unique_ptr<PendingQueryResult>
|
|
101516
|
+
ClientContext::PendingStatementOrPreparedStatement(ClientContextLock &lock, const string &query,
|
|
101517
|
+
unique_ptr<SQLStatement> statement,
|
|
101518
|
+
shared_ptr<PreparedStatementData> &prepared, vector<Value> *values) {
|
|
101519
|
+
unique_ptr<PendingQueryResult> result;
|
|
101520
|
+
|
|
101521
|
+
BeginQueryInternal(lock, query);
|
|
101288
101522
|
// start the profiler
|
|
101289
|
-
profiler
|
|
101523
|
+
auto &profiler = QueryProfiler::Get(*this);
|
|
101524
|
+
profiler.StartQuery(query, IsExplainAnalyze(statement ? statement.get() : prepared->unbound_statement.get()));
|
|
101525
|
+
bool invalidate_query = true;
|
|
101290
101526
|
try {
|
|
101291
101527
|
if (statement) {
|
|
101292
|
-
result =
|
|
101528
|
+
result = PendingStatementInternal(lock, query, move(statement));
|
|
101293
101529
|
} else {
|
|
101294
101530
|
auto &catalog = Catalog::GetCatalog(*this);
|
|
101295
101531
|
if (prepared->unbound_statement && catalog.GetCatalogVersion() != prepared->catalog_version) {
|
|
@@ -101302,68 +101538,22 @@ unique_ptr<QueryResult> ClientContext::RunStatementOrPreparedStatement(ClientCon
|
|
|
101302
101538
|
new_prepared->unbound_statement = move(prepared->unbound_statement);
|
|
101303
101539
|
prepared = move(new_prepared);
|
|
101304
101540
|
}
|
|
101305
|
-
result =
|
|
101541
|
+
result = PendingPreparedStatement(lock, prepared, *values);
|
|
101306
101542
|
}
|
|
101307
101543
|
} catch (StandardException &ex) {
|
|
101308
101544
|
// standard exceptions do not invalidate the current transaction
|
|
101309
|
-
result = make_unique<
|
|
101545
|
+
result = make_unique<PendingQueryResult>(ex.what());
|
|
101546
|
+
invalidate_query = false;
|
|
101310
101547
|
} catch (std::exception &ex) {
|
|
101311
101548
|
// other types of exceptions do invalidate the current transaction
|
|
101312
|
-
|
|
101313
|
-
ActiveTransaction().Invalidate();
|
|
101314
|
-
}
|
|
101315
|
-
result = make_unique<MaterializedQueryResult>(ex.what());
|
|
101549
|
+
result = make_unique<PendingQueryResult>(ex.what());
|
|
101316
101550
|
}
|
|
101317
101551
|
if (!result->success) {
|
|
101318
|
-
// initial failures should always be reported as MaterializedResult
|
|
101319
|
-
D_ASSERT(result->type != QueryResultType::STREAM_RESULT);
|
|
101320
101552
|
// query failed: abort now
|
|
101321
|
-
|
|
101553
|
+
EndQueryInternal(lock, false, invalidate_query);
|
|
101322
101554
|
return result;
|
|
101323
101555
|
}
|
|
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
|
-
}
|
|
101556
|
+
D_ASSERT(active_query->open_result == result.get());
|
|
101367
101557
|
return result;
|
|
101368
101558
|
}
|
|
101369
101559
|
|
|
@@ -101389,34 +101579,96 @@ void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) {
|
|
|
101389
101579
|
}
|
|
101390
101580
|
|
|
101391
101581
|
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);
|
|
101582
|
+
auto pending_query = PendingQuery(move(statement));
|
|
101583
|
+
return pending_query->Execute(allow_stream_result);
|
|
101399
101584
|
}
|
|
101400
101585
|
|
|
101401
101586
|
unique_ptr<QueryResult> ClientContext::Query(const string &query, bool allow_stream_result) {
|
|
101402
101587
|
auto lock = LockContext();
|
|
101403
|
-
LogQueryInternal(*lock, query);
|
|
101404
101588
|
|
|
101589
|
+
string error;
|
|
101405
101590
|
vector<unique_ptr<SQLStatement>> statements;
|
|
101591
|
+
if (!ParseStatements(*lock, query, statements, error)) {
|
|
101592
|
+
return make_unique<MaterializedQueryResult>(move(error));
|
|
101593
|
+
}
|
|
101594
|
+
if (statements.empty()) {
|
|
101595
|
+
// no statements, return empty successful result
|
|
101596
|
+
return make_unique<MaterializedQueryResult>(StatementType::INVALID_STATEMENT);
|
|
101597
|
+
}
|
|
101598
|
+
|
|
101599
|
+
unique_ptr<QueryResult> result;
|
|
101600
|
+
QueryResult *last_result = nullptr;
|
|
101601
|
+
for (idx_t i = 0; i < statements.size(); i++) {
|
|
101602
|
+
auto &statement = statements[i];
|
|
101603
|
+
bool is_last_statement = i + 1 == statements.size();
|
|
101604
|
+
bool stream_result = allow_stream_result && is_last_statement;
|
|
101605
|
+
auto pending_query = PendingQueryInternal(*lock, move(statement));
|
|
101606
|
+
unique_ptr<QueryResult> current_result;
|
|
101607
|
+
if (!pending_query->success) {
|
|
101608
|
+
current_result = make_unique<MaterializedQueryResult>(pending_query->error);
|
|
101609
|
+
} else {
|
|
101610
|
+
current_result = ExecutePendingQueryInternal(*lock, *pending_query, stream_result);
|
|
101611
|
+
}
|
|
101612
|
+
// now append the result to the list of results
|
|
101613
|
+
if (!last_result) {
|
|
101614
|
+
// first result of the query
|
|
101615
|
+
result = move(current_result);
|
|
101616
|
+
last_result = result.get();
|
|
101617
|
+
} else {
|
|
101618
|
+
// later results; attach to the result chain
|
|
101619
|
+
last_result->next = move(current_result);
|
|
101620
|
+
last_result = last_result->next.get();
|
|
101621
|
+
}
|
|
101622
|
+
}
|
|
101623
|
+
return result;
|
|
101624
|
+
}
|
|
101625
|
+
|
|
101626
|
+
bool ClientContext::ParseStatements(ClientContextLock &lock, const string &query,
|
|
101627
|
+
vector<unique_ptr<SQLStatement>> &result, string &error) {
|
|
101406
101628
|
try {
|
|
101407
|
-
InitialCleanup(
|
|
101629
|
+
InitialCleanup(lock);
|
|
101408
101630
|
// parse the query and transform it into a set of statements
|
|
101409
|
-
|
|
101631
|
+
result = ParseStatementsInternal(lock, query);
|
|
101632
|
+
return true;
|
|
101410
101633
|
} catch (std::exception &ex) {
|
|
101411
|
-
|
|
101634
|
+
error = ex.what();
|
|
101635
|
+
return false;
|
|
101412
101636
|
}
|
|
101637
|
+
}
|
|
101413
101638
|
|
|
101414
|
-
|
|
101415
|
-
|
|
101416
|
-
|
|
101639
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQuery(const string &query) {
|
|
101640
|
+
auto lock = LockContext();
|
|
101641
|
+
|
|
101642
|
+
string error;
|
|
101643
|
+
vector<unique_ptr<SQLStatement>> statements;
|
|
101644
|
+
if (!ParseStatements(*lock, query, statements, error)) {
|
|
101645
|
+
return make_unique<PendingQueryResult>(move(error));
|
|
101417
101646
|
}
|
|
101647
|
+
if (statements.size() != 1) {
|
|
101648
|
+
return make_unique<PendingQueryResult>("PendingQuery can only take a single statement");
|
|
101649
|
+
}
|
|
101650
|
+
return PendingQueryInternal(*lock, move(statements[0]));
|
|
101651
|
+
}
|
|
101418
101652
|
|
|
101419
|
-
|
|
101653
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQuery(unique_ptr<SQLStatement> statement) {
|
|
101654
|
+
auto lock = LockContext();
|
|
101655
|
+
return PendingQueryInternal(*lock, move(statement));
|
|
101656
|
+
}
|
|
101657
|
+
|
|
101658
|
+
unique_ptr<PendingQueryResult> ClientContext::PendingQueryInternal(ClientContextLock &lock,
|
|
101659
|
+
unique_ptr<SQLStatement> statement, bool verify) {
|
|
101660
|
+
auto query = statement->query;
|
|
101661
|
+
shared_ptr<PreparedStatementData> prepared;
|
|
101662
|
+
if (verify) {
|
|
101663
|
+
return PendingStatementOrPreparedStatementInternal(lock, query, move(statement), prepared, nullptr);
|
|
101664
|
+
} else {
|
|
101665
|
+
return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, nullptr);
|
|
101666
|
+
}
|
|
101667
|
+
}
|
|
101668
|
+
|
|
101669
|
+
unique_ptr<QueryResult> ClientContext::ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query,
|
|
101670
|
+
bool allow_stream_result) {
|
|
101671
|
+
return query.ExecuteInternal(lock, allow_stream_result);
|
|
101420
101672
|
}
|
|
101421
101673
|
|
|
101422
101674
|
void ClientContext::Interrupt() {
|
|
@@ -101425,12 +101677,14 @@ void ClientContext::Interrupt() {
|
|
|
101425
101677
|
|
|
101426
101678
|
void ClientContext::EnableProfiling() {
|
|
101427
101679
|
auto lock = LockContext();
|
|
101428
|
-
|
|
101680
|
+
auto &config = ClientConfig::GetConfig(*this);
|
|
101681
|
+
config.enable_profiler = true;
|
|
101429
101682
|
}
|
|
101430
101683
|
|
|
101431
101684
|
void ClientContext::DisableProfiling() {
|
|
101432
101685
|
auto lock = LockContext();
|
|
101433
|
-
|
|
101686
|
+
auto &config = ClientConfig::GetConfig(*this);
|
|
101687
|
+
config.enable_profiler = false;
|
|
101434
101688
|
}
|
|
101435
101689
|
|
|
101436
101690
|
string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query, unique_ptr<SQLStatement> statement) {
|
|
@@ -101492,9 +101746,10 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101492
101746
|
#endif
|
|
101493
101747
|
|
|
101494
101748
|
// disable profiling if it is enabled
|
|
101495
|
-
|
|
101749
|
+
auto &config = ClientConfig::GetConfig(*this);
|
|
101750
|
+
bool profiling_is_enabled = config.enable_profiler;
|
|
101496
101751
|
if (profiling_is_enabled) {
|
|
101497
|
-
|
|
101752
|
+
config.enable_profiler = false;
|
|
101498
101753
|
}
|
|
101499
101754
|
|
|
101500
101755
|
// see below
|
|
@@ -101511,7 +101766,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101511
101766
|
|
|
101512
101767
|
// execute the original statement
|
|
101513
101768
|
try {
|
|
101514
|
-
auto result = RunStatementInternal(lock, query, move(statement), false);
|
|
101769
|
+
auto result = RunStatementInternal(lock, query, move(statement), false, false);
|
|
101515
101770
|
original_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101516
101771
|
} catch (std::exception &ex) {
|
|
101517
101772
|
original_result->error = ex.what();
|
|
@@ -101524,7 +101779,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101524
101779
|
auto explain_q = "EXPLAIN " + query;
|
|
101525
101780
|
auto explain_stmt = make_unique<ExplainStatement>(move(statement_copy_for_explain));
|
|
101526
101781
|
try {
|
|
101527
|
-
RunStatementInternal(lock, explain_q, move(explain_stmt), false);
|
|
101782
|
+
RunStatementInternal(lock, explain_q, move(explain_stmt), false, false);
|
|
101528
101783
|
} catch (std::exception &ex) { // LCOV_EXCL_START
|
|
101529
101784
|
return "EXPLAIN failed but query did not (" + string(ex.what()) + ")";
|
|
101530
101785
|
} // LCOV_EXCL_STOP
|
|
@@ -101532,7 +101787,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101532
101787
|
|
|
101533
101788
|
// now execute the copied statement
|
|
101534
101789
|
try {
|
|
101535
|
-
auto result = RunStatementInternal(lock, query, move(copied_stmt), false);
|
|
101790
|
+
auto result = RunStatementInternal(lock, query, move(copied_stmt), false, false);
|
|
101536
101791
|
copied_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101537
101792
|
} catch (std::exception &ex) {
|
|
101538
101793
|
copied_result->error = ex.what();
|
|
@@ -101541,7 +101796,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101541
101796
|
}
|
|
101542
101797
|
// now execute the deserialized statement
|
|
101543
101798
|
try {
|
|
101544
|
-
auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false);
|
|
101799
|
+
auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false, false);
|
|
101545
101800
|
deserialized_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101546
101801
|
} catch (std::exception &ex) {
|
|
101547
101802
|
deserialized_result->error = ex.what();
|
|
@@ -101551,7 +101806,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101551
101806
|
// now execute the unoptimized statement
|
|
101552
101807
|
config.enable_optimizer = false;
|
|
101553
101808
|
try {
|
|
101554
|
-
auto result = RunStatementInternal(lock, query, move(unoptimized_stmt), false);
|
|
101809
|
+
auto result = RunStatementInternal(lock, query, move(unoptimized_stmt), false, false);
|
|
101555
101810
|
unoptimized_result = unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
101556
101811
|
} catch (std::exception &ex) {
|
|
101557
101812
|
unoptimized_result->error = ex.what();
|
|
@@ -101561,7 +101816,7 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
|
|
|
101561
101816
|
config.enable_optimizer = true;
|
|
101562
101817
|
|
|
101563
101818
|
if (profiling_is_enabled) {
|
|
101564
|
-
|
|
101819
|
+
config.enable_profiler = true;
|
|
101565
101820
|
}
|
|
101566
101821
|
|
|
101567
101822
|
// now compare the results
|
|
@@ -101615,7 +101870,7 @@ bool ClientContext::UpdateFunctionInfoFromEntry(ScalarFunctionCatalogEntry *exis
|
|
|
101615
101870
|
void ClientContext::RegisterFunction(CreateFunctionInfo *info) {
|
|
101616
101871
|
RunFunctionInTransaction([&]() {
|
|
101617
101872
|
auto &catalog = Catalog::GetCatalog(*this);
|
|
101618
|
-
|
|
101873
|
+
auto existing_function = (ScalarFunctionCatalogEntry *)catalog.GetEntry(
|
|
101619
101874
|
*this, CatalogType::SCALAR_FUNCTION_ENTRY, info->schema, info->name, true);
|
|
101620
101875
|
if (existing_function) {
|
|
101621
101876
|
if (UpdateFunctionInfoFromEntry(existing_function, (CreateScalarFunctionInfo *)info)) {
|
|
@@ -101637,6 +101892,7 @@ void ClientContext::RunFunctionInTransactionInternal(ClientContextLock &lock, co
|
|
|
101637
101892
|
// check if we are on AutoCommit. In this case we should start a transaction
|
|
101638
101893
|
bool require_new_transaction = transaction.IsAutoCommit() && !transaction.HasActiveTransaction();
|
|
101639
101894
|
if (require_new_transaction) {
|
|
101895
|
+
D_ASSERT(!active_query);
|
|
101640
101896
|
transaction.BeginTransaction();
|
|
101641
101897
|
}
|
|
101642
101898
|
try {
|
|
@@ -101751,12 +102007,14 @@ unique_ptr<QueryResult> ClientContext::Execute(const shared_ptr<Relation> &relat
|
|
|
101751
102007
|
// verify read only statements by running a select statement
|
|
101752
102008
|
auto select = make_unique<SelectStatement>();
|
|
101753
102009
|
select->node = relation->GetQueryNode();
|
|
101754
|
-
|
|
102010
|
+
RunStatementInternal(*lock, query, move(select), false);
|
|
101755
102011
|
}
|
|
101756
102012
|
}
|
|
101757
102013
|
auto &expected_columns = relation->Columns();
|
|
101758
102014
|
auto relation_stmt = make_unique<RelationStatement>(relation);
|
|
101759
|
-
|
|
102015
|
+
|
|
102016
|
+
unique_ptr<QueryResult> result;
|
|
102017
|
+
result = RunStatementInternal(*lock, query, move(relation_stmt), false);
|
|
101760
102018
|
if (!result->success) {
|
|
101761
102019
|
return result;
|
|
101762
102020
|
}
|
|
@@ -102528,10 +102786,11 @@ Connection::Connection(DuckDB &database) : Connection(*database.instance) {
|
|
|
102528
102786
|
}
|
|
102529
102787
|
|
|
102530
102788
|
string Connection::GetProfilingInformation(ProfilerPrintFormat format) {
|
|
102789
|
+
auto &profiler = QueryProfiler::Get(*context);
|
|
102531
102790
|
if (format == ProfilerPrintFormat::JSON) {
|
|
102532
|
-
return
|
|
102791
|
+
return profiler.ToJSON();
|
|
102533
102792
|
} else {
|
|
102534
|
-
return
|
|
102793
|
+
return profiler.ToString();
|
|
102535
102794
|
}
|
|
102536
102795
|
}
|
|
102537
102796
|
|
|
@@ -102575,6 +102834,14 @@ unique_ptr<MaterializedQueryResult> Connection::Query(unique_ptr<SQLStatement> s
|
|
|
102575
102834
|
return unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
|
|
102576
102835
|
}
|
|
102577
102836
|
|
|
102837
|
+
unique_ptr<PendingQueryResult> Connection::PendingQuery(const string &query) {
|
|
102838
|
+
return context->PendingQuery(query);
|
|
102839
|
+
}
|
|
102840
|
+
|
|
102841
|
+
unique_ptr<PendingQueryResult> Connection::PendingQuery(unique_ptr<SQLStatement> statement) {
|
|
102842
|
+
return context->PendingQuery(move(statement));
|
|
102843
|
+
}
|
|
102844
|
+
|
|
102578
102845
|
unique_ptr<PreparedStatement> Connection::Prepare(const string &query) {
|
|
102579
102846
|
return context->Prepare(query);
|
|
102580
102847
|
}
|
|
@@ -110883,6 +111150,75 @@ unique_ptr<DataChunk> MaterializedQueryResult::FetchRaw() {
|
|
|
110883
111150
|
|
|
110884
111151
|
|
|
110885
111152
|
|
|
111153
|
+
namespace duckdb {
|
|
111154
|
+
|
|
111155
|
+
PendingQueryResult::PendingQueryResult(shared_ptr<ClientContext> context_p, PreparedStatementData &statement,
|
|
111156
|
+
vector<LogicalType> types_p)
|
|
111157
|
+
: BaseQueryResult(QueryResultType::PENDING_RESULT, statement.statement_type, move(types_p), statement.names),
|
|
111158
|
+
context(move(context_p)) {
|
|
111159
|
+
}
|
|
111160
|
+
|
|
111161
|
+
PendingQueryResult::PendingQueryResult(string error) : BaseQueryResult(QueryResultType::PENDING_RESULT, move(error)) {
|
|
111162
|
+
}
|
|
111163
|
+
|
|
111164
|
+
PendingQueryResult::~PendingQueryResult() {
|
|
111165
|
+
}
|
|
111166
|
+
|
|
111167
|
+
unique_ptr<ClientContextLock> PendingQueryResult::LockContext() {
|
|
111168
|
+
if (!context) {
|
|
111169
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
111170
|
+
error);
|
|
111171
|
+
}
|
|
111172
|
+
return context->LockContext();
|
|
111173
|
+
}
|
|
111174
|
+
|
|
111175
|
+
void PendingQueryResult::CheckExecutableInternal(ClientContextLock &lock) {
|
|
111176
|
+
bool invalidated = !success || !context;
|
|
111177
|
+
if (!invalidated) {
|
|
111178
|
+
invalidated = !context->IsActiveResult(lock, this);
|
|
111179
|
+
}
|
|
111180
|
+
if (invalidated) {
|
|
111181
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
111182
|
+
error);
|
|
111183
|
+
}
|
|
111184
|
+
}
|
|
111185
|
+
|
|
111186
|
+
PendingExecutionResult PendingQueryResult::ExecuteTask() {
|
|
111187
|
+
auto lock = LockContext();
|
|
111188
|
+
return ExecuteTaskInternal(*lock);
|
|
111189
|
+
}
|
|
111190
|
+
|
|
111191
|
+
PendingExecutionResult PendingQueryResult::ExecuteTaskInternal(ClientContextLock &lock) {
|
|
111192
|
+
CheckExecutableInternal(lock);
|
|
111193
|
+
return context->ExecuteTaskInternal(lock, *this);
|
|
111194
|
+
}
|
|
111195
|
+
|
|
111196
|
+
unique_ptr<QueryResult> PendingQueryResult::ExecuteInternal(ClientContextLock &lock, bool allow_streaming_result) {
|
|
111197
|
+
CheckExecutableInternal(lock);
|
|
111198
|
+
while (ExecuteTaskInternal(lock) == PendingExecutionResult::RESULT_NOT_READY) {
|
|
111199
|
+
}
|
|
111200
|
+
if (!success) {
|
|
111201
|
+
return make_unique<MaterializedQueryResult>(error);
|
|
111202
|
+
}
|
|
111203
|
+
auto result = context->FetchResultInternal(lock, *this, allow_streaming_result);
|
|
111204
|
+
Close();
|
|
111205
|
+
return result;
|
|
111206
|
+
}
|
|
111207
|
+
|
|
111208
|
+
unique_ptr<QueryResult> PendingQueryResult::Execute(bool allow_streaming_result) {
|
|
111209
|
+
auto lock = LockContext();
|
|
111210
|
+
return ExecuteInternal(*lock, allow_streaming_result);
|
|
111211
|
+
}
|
|
111212
|
+
|
|
111213
|
+
void PendingQueryResult::Close() {
|
|
111214
|
+
context.reset();
|
|
111215
|
+
}
|
|
111216
|
+
|
|
111217
|
+
} // namespace duckdb
|
|
111218
|
+
|
|
111219
|
+
|
|
111220
|
+
|
|
111221
|
+
|
|
110886
111222
|
|
|
110887
111223
|
namespace duckdb {
|
|
110888
111224
|
|
|
@@ -110919,11 +111255,19 @@ const vector<string> &PreparedStatement::GetNames() {
|
|
|
110919
111255
|
}
|
|
110920
111256
|
|
|
110921
111257
|
unique_ptr<QueryResult> PreparedStatement::Execute(vector<Value> &values, bool allow_stream_result) {
|
|
111258
|
+
auto pending = PendingQuery(values);
|
|
111259
|
+
if (!pending->success) {
|
|
111260
|
+
return make_unique<MaterializedQueryResult>(pending->error);
|
|
111261
|
+
}
|
|
111262
|
+
return pending->Execute(allow_stream_result && data->allow_stream_result);
|
|
111263
|
+
}
|
|
111264
|
+
|
|
111265
|
+
unique_ptr<PendingQueryResult> PreparedStatement::PendingQuery(vector<Value> &values) {
|
|
110922
111266
|
if (!success) {
|
|
110923
111267
|
throw InvalidInputException("Attempting to execute an unsuccessfully prepared statement!");
|
|
110924
111268
|
}
|
|
110925
111269
|
D_ASSERT(data);
|
|
110926
|
-
auto result = context->
|
|
111270
|
+
auto result = context->PendingQuery(query, data, values);
|
|
110927
111271
|
return result;
|
|
110928
111272
|
}
|
|
110929
111273
|
|
|
@@ -111009,16 +111353,42 @@ using std::ofstream;
|
|
|
111009
111353
|
|
|
111010
111354
|
|
|
111011
111355
|
|
|
111356
|
+
|
|
111357
|
+
|
|
111012
111358
|
#include <utility>
|
|
111013
111359
|
#include <algorithm>
|
|
111014
111360
|
|
|
111015
111361
|
namespace duckdb {
|
|
111016
111362
|
|
|
111363
|
+
QueryProfiler::QueryProfiler(ClientContext &context_p)
|
|
111364
|
+
: context(context_p), running(false), query_requires_profiling(false), is_explain_analyze(false) {
|
|
111365
|
+
}
|
|
111366
|
+
|
|
111367
|
+
bool QueryProfiler::IsEnabled() const {
|
|
111368
|
+
return is_explain_analyze ? true : ClientConfig::GetConfig(context).enable_profiler;
|
|
111369
|
+
}
|
|
111370
|
+
|
|
111371
|
+
bool QueryProfiler::IsDetailedEnabled() const {
|
|
111372
|
+
return is_explain_analyze ? false : ClientConfig::GetConfig(context).enable_detailed_profiling;
|
|
111373
|
+
}
|
|
111374
|
+
|
|
111375
|
+
ProfilerPrintFormat QueryProfiler::GetPrintFormat() const {
|
|
111376
|
+
return is_explain_analyze ? ProfilerPrintFormat::NONE : ClientConfig::GetConfig(context).profiler_print_format;
|
|
111377
|
+
}
|
|
111378
|
+
|
|
111379
|
+
string QueryProfiler::GetSaveLocation() const {
|
|
111380
|
+
return is_explain_analyze ? string() : ClientConfig::GetConfig(context).profiler_save_location;
|
|
111381
|
+
}
|
|
111382
|
+
|
|
111383
|
+
QueryProfiler &QueryProfiler::Get(ClientContext &context) {
|
|
111384
|
+
return *context.profiler;
|
|
111385
|
+
}
|
|
111386
|
+
|
|
111017
111387
|
void QueryProfiler::StartQuery(string query, bool is_explain_analyze) {
|
|
111018
111388
|
if (is_explain_analyze) {
|
|
111019
111389
|
StartExplainAnalyze();
|
|
111020
111390
|
}
|
|
111021
|
-
if (!
|
|
111391
|
+
if (!IsEnabled()) {
|
|
111022
111392
|
return;
|
|
111023
111393
|
}
|
|
111024
111394
|
this->running = true;
|
|
@@ -111076,17 +111446,10 @@ void QueryProfiler::Finalize(TreeNode &node) {
|
|
|
111076
111446
|
|
|
111077
111447
|
void QueryProfiler::StartExplainAnalyze() {
|
|
111078
111448
|
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
111449
|
}
|
|
111087
111450
|
|
|
111088
111451
|
void QueryProfiler::EndQuery() {
|
|
111089
|
-
if (!
|
|
111452
|
+
if (!IsEnabled() || !running) {
|
|
111090
111453
|
return;
|
|
111091
111454
|
}
|
|
111092
111455
|
|
|
@@ -111095,6 +111458,7 @@ void QueryProfiler::EndQuery() {
|
|
|
111095
111458
|
Finalize(*root);
|
|
111096
111459
|
}
|
|
111097
111460
|
this->running = false;
|
|
111461
|
+
auto automatic_print_format = GetPrintFormat();
|
|
111098
111462
|
// print or output the query profiling after termination, if this is enabled
|
|
111099
111463
|
if (automatic_print_format != ProfilerPrintFormat::NONE) {
|
|
111100
111464
|
// check if this query should be output based on the operator types
|
|
@@ -111106,7 +111470,7 @@ void QueryProfiler::EndQuery() {
|
|
|
111106
111470
|
} else if (automatic_print_format == ProfilerPrintFormat::QUERY_TREE_OPTIMIZER) {
|
|
111107
111471
|
query_info = ToString(true);
|
|
111108
111472
|
}
|
|
111109
|
-
|
|
111473
|
+
auto save_location = GetSaveLocation();
|
|
111110
111474
|
if (save_location.empty()) {
|
|
111111
111475
|
Printer::Print(query_info);
|
|
111112
111476
|
Printer::Print("\n");
|
|
@@ -111114,16 +111478,11 @@ void QueryProfiler::EndQuery() {
|
|
|
111114
111478
|
WriteToFile(save_location.c_str(), query_info);
|
|
111115
111479
|
}
|
|
111116
111480
|
}
|
|
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
|
-
}
|
|
111481
|
+
this->is_explain_analyze = false;
|
|
111123
111482
|
}
|
|
111124
111483
|
|
|
111125
111484
|
void QueryProfiler::StartPhase(string new_phase) {
|
|
111126
|
-
if (!
|
|
111485
|
+
if (!IsEnabled() || !running) {
|
|
111127
111486
|
return;
|
|
111128
111487
|
}
|
|
111129
111488
|
|
|
@@ -111147,7 +111506,7 @@ void QueryProfiler::StartPhase(string new_phase) {
|
|
|
111147
111506
|
}
|
|
111148
111507
|
|
|
111149
111508
|
void QueryProfiler::EndPhase() {
|
|
111150
|
-
if (!
|
|
111509
|
+
if (!IsEnabled() || !running) {
|
|
111151
111510
|
return;
|
|
111152
111511
|
}
|
|
111153
111512
|
D_ASSERT(phase_stack.size() > 0);
|
|
@@ -111167,7 +111526,7 @@ void QueryProfiler::EndPhase() {
|
|
|
111167
111526
|
}
|
|
111168
111527
|
|
|
111169
111528
|
void QueryProfiler::Initialize(PhysicalOperator *root_op) {
|
|
111170
|
-
if (!
|
|
111529
|
+
if (!IsEnabled() || !running) {
|
|
111171
111530
|
return;
|
|
111172
111531
|
}
|
|
111173
111532
|
this->query_requires_profiling = false;
|
|
@@ -111248,7 +111607,7 @@ void OperatorProfiler::Flush(const PhysicalOperator *phys_op, ExpressionExecutor
|
|
|
111248
111607
|
}
|
|
111249
111608
|
|
|
111250
111609
|
void QueryProfiler::Flush(OperatorProfiler &profiler) {
|
|
111251
|
-
if (!
|
|
111610
|
+
if (!IsEnabled() || !running) {
|
|
111252
111611
|
return;
|
|
111253
111612
|
}
|
|
111254
111613
|
lock_guard<mutex> guard(flush_lock);
|
|
@@ -111258,7 +111617,7 @@ void QueryProfiler::Flush(OperatorProfiler &profiler) {
|
|
|
111258
111617
|
|
|
111259
111618
|
entry->second->info.time += node.second.time;
|
|
111260
111619
|
entry->second->info.elements += node.second.elements;
|
|
111261
|
-
if (!
|
|
111620
|
+
if (!IsDetailedEnabled()) {
|
|
111262
111621
|
continue;
|
|
111263
111622
|
}
|
|
111264
111623
|
for (auto &info : node.second.executors_info) {
|
|
@@ -111319,7 +111678,7 @@ string QueryProfiler::ToString(bool print_optimizer_output) const {
|
|
|
111319
111678
|
}
|
|
111320
111679
|
|
|
111321
111680
|
void QueryProfiler::ToStream(std::ostream &ss, bool print_optimizer_output) const {
|
|
111322
|
-
if (!
|
|
111681
|
+
if (!IsEnabled()) {
|
|
111323
111682
|
ss << "Query profiling is disabled. Call "
|
|
111324
111683
|
"Connection::EnableProfiling() to enable profiling!";
|
|
111325
111684
|
return;
|
|
@@ -111490,7 +111849,7 @@ static void ToJSONRecursive(QueryProfiler::TreeNode &node, std::ostream &ss, int
|
|
|
111490
111849
|
}
|
|
111491
111850
|
|
|
111492
111851
|
string QueryProfiler::ToJSON() const {
|
|
111493
|
-
if (!
|
|
111852
|
+
if (!IsEnabled()) {
|
|
111494
111853
|
return "{ \"result\": \"disabled\" }\n";
|
|
111495
111854
|
}
|
|
111496
111855
|
if (query.empty()) {
|
|
@@ -111605,10 +111964,6 @@ vector<QueryProfiler::PhaseTimingItem> QueryProfiler::GetOrderedPhaseTimings() c
|
|
|
111605
111964
|
return result;
|
|
111606
111965
|
}
|
|
111607
111966
|
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
111967
|
}
|
|
111613
111968
|
|
|
111614
111969
|
void ExpressionInfo::ExtractExpressionsRecursive(unique_ptr<ExpressionState> &state) {
|
|
@@ -111665,17 +112020,44 @@ ExpressionRootInfo::ExpressionRootInfo(ExpressionExecutorState &state, string na
|
|
|
111665
112020
|
|
|
111666
112021
|
namespace duckdb {
|
|
111667
112022
|
|
|
111668
|
-
|
|
112023
|
+
BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type)
|
|
111669
112024
|
: type(type), statement_type(statement_type), success(true) {
|
|
111670
112025
|
}
|
|
111671
112026
|
|
|
111672
|
-
|
|
111673
|
-
|
|
112027
|
+
BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type, vector<LogicalType> types_p,
|
|
112028
|
+
vector<string> names_p)
|
|
111674
112029
|
: type(type), statement_type(statement_type), types(move(types_p)), names(move(names_p)), success(true) {
|
|
111675
112030
|
D_ASSERT(types.size() == names.size());
|
|
111676
112031
|
}
|
|
111677
112032
|
|
|
111678
|
-
|
|
112033
|
+
BaseQueryResult::BaseQueryResult(QueryResultType type, string error) : type(type), success(false), error(move(error)) {
|
|
112034
|
+
}
|
|
112035
|
+
|
|
112036
|
+
BaseQueryResult::~BaseQueryResult() {
|
|
112037
|
+
}
|
|
112038
|
+
|
|
112039
|
+
bool BaseQueryResult::HasError() {
|
|
112040
|
+
return !success;
|
|
112041
|
+
}
|
|
112042
|
+
const string &BaseQueryResult::GetError() {
|
|
112043
|
+
return error;
|
|
112044
|
+
}
|
|
112045
|
+
idx_t BaseQueryResult::ColumnCount() {
|
|
112046
|
+
return types.size();
|
|
112047
|
+
}
|
|
112048
|
+
|
|
112049
|
+
QueryResult::QueryResult(QueryResultType type, StatementType statement_type) : BaseQueryResult(type, statement_type) {
|
|
112050
|
+
}
|
|
112051
|
+
|
|
112052
|
+
QueryResult::QueryResult(QueryResultType type, StatementType statement_type, vector<LogicalType> types_p,
|
|
112053
|
+
vector<string> names_p)
|
|
112054
|
+
: BaseQueryResult(type, statement_type, move(types_p), move(names_p)) {
|
|
112055
|
+
}
|
|
112056
|
+
|
|
112057
|
+
QueryResult::QueryResult(QueryResultType type, string error) : BaseQueryResult(type, move(error)) {
|
|
112058
|
+
}
|
|
112059
|
+
|
|
112060
|
+
QueryResult::~QueryResult() {
|
|
111679
112061
|
}
|
|
111680
112062
|
|
|
111681
112063
|
unique_ptr<DataChunk> QueryResult::Fetch() {
|
|
@@ -114694,24 +115076,27 @@ Value EnableObjectCacheSetting::GetSetting(ClientContext &context) {
|
|
|
114694
115076
|
//===--------------------------------------------------------------------===//
|
|
114695
115077
|
void EnableProfilingSetting::SetLocal(ClientContext &context, const Value &input) {
|
|
114696
115078
|
auto parameter = StringUtil::Lower(input.ToString());
|
|
115079
|
+
|
|
115080
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
114697
115081
|
if (parameter == "json") {
|
|
114698
|
-
|
|
115082
|
+
config.profiler_print_format = ProfilerPrintFormat::JSON;
|
|
114699
115083
|
} else if (parameter == "query_tree") {
|
|
114700
|
-
|
|
115084
|
+
config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE;
|
|
114701
115085
|
} else if (parameter == "query_tree_optimizer") {
|
|
114702
|
-
|
|
115086
|
+
config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE_OPTIMIZER;
|
|
114703
115087
|
} else {
|
|
114704
115088
|
throw ParserException(
|
|
114705
115089
|
"Unrecognized print format %s, supported formats: [json, query_tree, query_tree_optimizer]", parameter);
|
|
114706
115090
|
}
|
|
114707
|
-
|
|
115091
|
+
config.enable_profiler = true;
|
|
114708
115092
|
}
|
|
114709
115093
|
|
|
114710
115094
|
Value EnableProfilingSetting::GetSetting(ClientContext &context) {
|
|
114711
|
-
|
|
115095
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
115096
|
+
if (!config.enable_profiler) {
|
|
114712
115097
|
return Value();
|
|
114713
115098
|
}
|
|
114714
|
-
switch (
|
|
115099
|
+
switch (config.profiler_print_format) {
|
|
114715
115100
|
case ProfilerPrintFormat::NONE:
|
|
114716
115101
|
return Value("none");
|
|
114717
115102
|
case ProfilerPrintFormat::JSON:
|
|
@@ -114855,12 +115240,14 @@ Value ProfilerHistorySize::GetSetting(ClientContext &context) {
|
|
|
114855
115240
|
// Profile Output
|
|
114856
115241
|
//===--------------------------------------------------------------------===//
|
|
114857
115242
|
void ProfileOutputSetting::SetLocal(ClientContext &context, const Value &input) {
|
|
115243
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
114858
115244
|
auto parameter = input.ToString();
|
|
114859
|
-
|
|
115245
|
+
config.profiler_save_location = parameter;
|
|
114860
115246
|
}
|
|
114861
115247
|
|
|
114862
115248
|
Value ProfileOutputSetting::GetSetting(ClientContext &context) {
|
|
114863
|
-
|
|
115249
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
115250
|
+
return Value(config.profiler_save_location);
|
|
114864
115251
|
}
|
|
114865
115252
|
|
|
114866
115253
|
//===--------------------------------------------------------------------===//
|
|
@@ -114868,17 +115255,24 @@ Value ProfileOutputSetting::GetSetting(ClientContext &context) {
|
|
|
114868
115255
|
//===--------------------------------------------------------------------===//
|
|
114869
115256
|
void ProfilingModeSetting::SetLocal(ClientContext &context, const Value &input) {
|
|
114870
115257
|
auto parameter = StringUtil::Lower(input.ToString());
|
|
115258
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
114871
115259
|
if (parameter == "standard") {
|
|
114872
|
-
|
|
115260
|
+
config.enable_profiler = true;
|
|
115261
|
+
config.enable_detailed_profiling = false;
|
|
114873
115262
|
} else if (parameter == "detailed") {
|
|
114874
|
-
|
|
115263
|
+
config.enable_profiler = true;
|
|
115264
|
+
config.enable_detailed_profiling = true;
|
|
114875
115265
|
} else {
|
|
114876
115266
|
throw ParserException("Unrecognized profiling mode \"%s\", supported formats: [standard, detailed]", parameter);
|
|
114877
115267
|
}
|
|
114878
115268
|
}
|
|
114879
115269
|
|
|
114880
115270
|
Value ProfilingModeSetting::GetSetting(ClientContext &context) {
|
|
114881
|
-
|
|
115271
|
+
auto &config = ClientConfig::GetConfig(context);
|
|
115272
|
+
if (!config.enable_profiler) {
|
|
115273
|
+
return Value();
|
|
115274
|
+
}
|
|
115275
|
+
return Value(config.enable_detailed_profiling ? "detailed" : "standard");
|
|
114882
115276
|
}
|
|
114883
115277
|
|
|
114884
115278
|
//===--------------------------------------------------------------------===//
|
|
@@ -114958,14 +115352,11 @@ Value ThreadsSetting::GetSetting(ClientContext &context) {
|
|
|
114958
115352
|
namespace duckdb {
|
|
114959
115353
|
|
|
114960
115354
|
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)) {
|
|
115355
|
+
vector<LogicalType> types, vector<string> names)
|
|
115356
|
+
: QueryResult(QueryResultType::STREAM_RESULT, statement_type, move(types), move(names)), context(move(context)) {
|
|
114965
115357
|
}
|
|
114966
115358
|
|
|
114967
115359
|
StreamQueryResult::~StreamQueryResult() {
|
|
114968
|
-
Close();
|
|
114969
115360
|
}
|
|
114970
115361
|
|
|
114971
115362
|
string StreamQueryResult::ToString() {
|
|
@@ -114979,12 +115370,28 @@ string StreamQueryResult::ToString() {
|
|
|
114979
115370
|
return result;
|
|
114980
115371
|
}
|
|
114981
115372
|
|
|
115373
|
+
unique_ptr<ClientContextLock> StreamQueryResult::LockContext() {
|
|
115374
|
+
if (!context) {
|
|
115375
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
115376
|
+
error);
|
|
115377
|
+
}
|
|
115378
|
+
return context->LockContext();
|
|
115379
|
+
}
|
|
115380
|
+
|
|
115381
|
+
void StreamQueryResult::CheckExecutableInternal(ClientContextLock &lock) {
|
|
115382
|
+
if (!IsOpenInternal(lock)) {
|
|
115383
|
+
throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s",
|
|
115384
|
+
error);
|
|
115385
|
+
}
|
|
115386
|
+
}
|
|
115387
|
+
|
|
114982
115388
|
unique_ptr<DataChunk> StreamQueryResult::FetchRaw() {
|
|
114983
|
-
|
|
114984
|
-
|
|
114985
|
-
|
|
115389
|
+
unique_ptr<DataChunk> chunk;
|
|
115390
|
+
{
|
|
115391
|
+
auto lock = LockContext();
|
|
115392
|
+
CheckExecutableInternal(*lock);
|
|
115393
|
+
chunk = context->Fetch(*lock, *this);
|
|
114986
115394
|
}
|
|
114987
|
-
auto chunk = context->Fetch();
|
|
114988
115395
|
if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) {
|
|
114989
115396
|
Close();
|
|
114990
115397
|
return nullptr;
|
|
@@ -115010,12 +115417,24 @@ unique_ptr<MaterializedQueryResult> StreamQueryResult::Materialize() {
|
|
|
115010
115417
|
return result;
|
|
115011
115418
|
}
|
|
115012
115419
|
|
|
115013
|
-
|
|
115014
|
-
|
|
115015
|
-
|
|
115420
|
+
bool StreamQueryResult::IsOpenInternal(ClientContextLock &lock) {
|
|
115421
|
+
bool invalidated = !success || !context;
|
|
115422
|
+
if (!invalidated) {
|
|
115423
|
+
invalidated = !context->IsActiveResult(lock, this);
|
|
115016
115424
|
}
|
|
115017
|
-
|
|
115018
|
-
|
|
115425
|
+
return !invalidated;
|
|
115426
|
+
}
|
|
115427
|
+
|
|
115428
|
+
bool StreamQueryResult::IsOpen() {
|
|
115429
|
+
if (!success || !context) {
|
|
115430
|
+
return false;
|
|
115431
|
+
}
|
|
115432
|
+
auto lock = LockContext();
|
|
115433
|
+
return IsOpenInternal(*lock);
|
|
115434
|
+
}
|
|
115435
|
+
|
|
115436
|
+
void StreamQueryResult::Close() {
|
|
115437
|
+
context.reset();
|
|
115019
115438
|
}
|
|
115020
115439
|
|
|
115021
115440
|
} // namespace duckdb
|
|
@@ -119810,9 +120229,10 @@ void Optimizer::RunOptimizer(OptimizerType type, const std::function<void()> &ca
|
|
|
119810
120229
|
// optimizer is marked as disabled: skip
|
|
119811
120230
|
return;
|
|
119812
120231
|
}
|
|
119813
|
-
|
|
120232
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
120233
|
+
profiler.StartPhase(OptimizerTypeToString(type));
|
|
119814
120234
|
callback();
|
|
119815
|
-
|
|
120235
|
+
profiler.EndPhase();
|
|
119816
120236
|
}
|
|
119817
120237
|
|
|
119818
120238
|
unique_ptr<LogicalOperator> Optimizer::Optimize(unique_ptr<LogicalOperator> plan) {
|
|
@@ -123771,6 +124191,10 @@ public:
|
|
|
123771
124191
|
|
|
123772
124192
|
//! Fully execute a pipeline with a source and a sink until the source is completely exhausted
|
|
123773
124193
|
void Execute();
|
|
124194
|
+
//! Execute a pipeline with a source and a sink until finished, or until max_chunks have been processed
|
|
124195
|
+
//! Returns true if execution is finished, false if Execute should be called again
|
|
124196
|
+
bool Execute(idx_t max_chunks);
|
|
124197
|
+
|
|
123774
124198
|
//! Push a single input DataChunk into the pipeline.
|
|
123775
124199
|
//! Returns either OperatorResultType::NEED_MORE_INPUT or OperatorResultType::FINISHED
|
|
123776
124200
|
//! If OperatorResultType::FINISHED is returned, more input will not change the result anymore
|
|
@@ -123939,7 +124363,7 @@ Executor::~Executor() {
|
|
|
123939
124363
|
}
|
|
123940
124364
|
|
|
123941
124365
|
Executor &Executor::Get(ClientContext &context) {
|
|
123942
|
-
return context.
|
|
124366
|
+
return context.GetExecutor();
|
|
123943
124367
|
}
|
|
123944
124368
|
|
|
123945
124369
|
void Executor::AddEvent(shared_ptr<Event> event) {
|
|
@@ -124168,16 +124592,6 @@ void Executor::VerifyPipelines() {
|
|
|
124168
124592
|
#endif
|
|
124169
124593
|
}
|
|
124170
124594
|
|
|
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
124595
|
void Executor::Initialize(PhysicalOperator *plan) {
|
|
124182
124596
|
Reset();
|
|
124183
124597
|
|
|
@@ -124186,7 +124600,8 @@ void Executor::Initialize(PhysicalOperator *plan) {
|
|
|
124186
124600
|
lock_guard<mutex> elock(executor_lock);
|
|
124187
124601
|
physical_plan = plan;
|
|
124188
124602
|
|
|
124189
|
-
|
|
124603
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
124604
|
+
profiler.Initialize(physical_plan);
|
|
124190
124605
|
this->producer = scheduler.CreateProducer();
|
|
124191
124606
|
|
|
124192
124607
|
auto root_pipeline = make_shared<Pipeline>(*this);
|
|
@@ -124202,60 +124617,102 @@ void Executor::Initialize(PhysicalOperator *plan) {
|
|
|
124202
124617
|
|
|
124203
124618
|
ScheduleEvents();
|
|
124204
124619
|
}
|
|
124620
|
+
}
|
|
124205
124621
|
|
|
124206
|
-
|
|
124207
|
-
|
|
124208
|
-
|
|
124209
|
-
|
|
124210
|
-
|
|
124211
|
-
|
|
124622
|
+
void Executor::CancelTasks() {
|
|
124623
|
+
task.reset();
|
|
124624
|
+
// we do this by creating weak pointers to all pipelines
|
|
124625
|
+
// then clearing our references to the pipelines
|
|
124626
|
+
// and waiting until all pipelines have been destroyed
|
|
124627
|
+
vector<weak_ptr<Pipeline>> weak_references;
|
|
124628
|
+
{
|
|
124629
|
+
lock_guard<mutex> elock(executor_lock);
|
|
124630
|
+
if (pipelines.empty()) {
|
|
124631
|
+
return;
|
|
124212
124632
|
}
|
|
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) {
|
|
124633
|
+
weak_references.reserve(pipelines.size());
|
|
124634
|
+
for (auto &pipeline : pipelines) {
|
|
124635
|
+
weak_references.push_back(weak_ptr<Pipeline>(pipeline));
|
|
124636
|
+
}
|
|
124637
|
+
for (auto &kv : union_pipelines) {
|
|
124638
|
+
for (auto &pipeline : kv.second) {
|
|
124224
124639
|
weak_references.push_back(weak_ptr<Pipeline>(pipeline));
|
|
124225
124640
|
}
|
|
124226
|
-
|
|
124227
|
-
|
|
124228
|
-
|
|
124229
|
-
|
|
124641
|
+
}
|
|
124642
|
+
for (auto &kv : child_pipelines) {
|
|
124643
|
+
for (auto &pipeline : kv.second) {
|
|
124644
|
+
weak_references.push_back(weak_ptr<Pipeline>(pipeline));
|
|
124230
124645
|
}
|
|
124231
|
-
|
|
124232
|
-
|
|
124233
|
-
|
|
124234
|
-
|
|
124646
|
+
}
|
|
124647
|
+
pipelines.clear();
|
|
124648
|
+
union_pipelines.clear();
|
|
124649
|
+
child_pipelines.clear();
|
|
124650
|
+
events.clear();
|
|
124651
|
+
}
|
|
124652
|
+
WorkOnTasks();
|
|
124653
|
+
for (auto &weak_ref : weak_references) {
|
|
124654
|
+
while (true) {
|
|
124655
|
+
auto weak = weak_ref.lock();
|
|
124656
|
+
if (!weak) {
|
|
124657
|
+
break;
|
|
124235
124658
|
}
|
|
124236
|
-
pipelines.clear();
|
|
124237
|
-
union_pipelines.clear();
|
|
124238
|
-
child_pipelines.clear();
|
|
124239
|
-
events.clear();
|
|
124240
124659
|
}
|
|
124241
|
-
|
|
124242
|
-
|
|
124243
|
-
|
|
124244
|
-
|
|
124245
|
-
|
|
124246
|
-
|
|
124660
|
+
}
|
|
124661
|
+
}
|
|
124662
|
+
|
|
124663
|
+
void Executor::WorkOnTasks() {
|
|
124664
|
+
auto &scheduler = TaskScheduler::GetScheduler(context);
|
|
124665
|
+
|
|
124666
|
+
unique_ptr<Task> task;
|
|
124667
|
+
while (scheduler.GetTaskFromProducer(*producer, task)) {
|
|
124668
|
+
task->Execute(TaskExecutionMode::PROCESS_ALL);
|
|
124669
|
+
task.reset();
|
|
124670
|
+
}
|
|
124671
|
+
}
|
|
124672
|
+
|
|
124673
|
+
PendingExecutionResult Executor::ExecuteTask() {
|
|
124674
|
+
if (execution_result != PendingExecutionResult::RESULT_NOT_READY) {
|
|
124675
|
+
return execution_result;
|
|
124676
|
+
}
|
|
124677
|
+
// check if there are any incomplete pipelines
|
|
124678
|
+
auto &scheduler = TaskScheduler::GetScheduler(context);
|
|
124679
|
+
while (completed_pipelines < total_pipelines) {
|
|
124680
|
+
// there are! if we don't already have a task, fetch one
|
|
124681
|
+
if (!task) {
|
|
124682
|
+
scheduler.GetTaskFromProducer(*producer, task);
|
|
124683
|
+
}
|
|
124684
|
+
if (task) {
|
|
124685
|
+
// if we have a task, partially process it
|
|
124686
|
+
auto result = task->Execute(TaskExecutionMode::PROCESS_PARTIAL);
|
|
124687
|
+
if (result != TaskExecutionResult::TASK_NOT_FINISHED) {
|
|
124688
|
+
// if the task is finished, clean it up
|
|
124689
|
+
task.reset();
|
|
124247
124690
|
}
|
|
124248
124691
|
}
|
|
124692
|
+
if (!HasError()) {
|
|
124693
|
+
// we (partially) processed a task and no exceptions were thrown
|
|
124694
|
+
// give back control to the caller
|
|
124695
|
+
return PendingExecutionResult::RESULT_NOT_READY;
|
|
124696
|
+
}
|
|
124697
|
+
execution_result = PendingExecutionResult::EXECUTION_ERROR;
|
|
124698
|
+
|
|
124699
|
+
// an exception has occurred executing one of the pipelines
|
|
124700
|
+
// we need to cancel all tasks associated with this executor
|
|
124701
|
+
CancelTasks();
|
|
124249
124702
|
ThrowException();
|
|
124250
124703
|
}
|
|
124704
|
+
D_ASSERT(!task);
|
|
124251
124705
|
|
|
124252
124706
|
lock_guard<mutex> elock(executor_lock);
|
|
124253
124707
|
pipelines.clear();
|
|
124254
124708
|
NextExecutor();
|
|
124255
124709
|
if (!exceptions.empty()) { // LCOV_EXCL_START
|
|
124256
124710
|
// an exception has occurred executing one of the pipelines
|
|
124711
|
+
execution_result = PendingExecutionResult::EXECUTION_ERROR;
|
|
124257
124712
|
ThrowExceptionInternal();
|
|
124258
124713
|
} // LCOV_EXCL_STOP
|
|
124714
|
+
execution_result = PendingExecutionResult::RESULT_READY;
|
|
124715
|
+
return execution_result;
|
|
124259
124716
|
}
|
|
124260
124717
|
|
|
124261
124718
|
void Executor::Reset() {
|
|
@@ -124274,6 +124731,7 @@ void Executor::Reset() {
|
|
|
124274
124731
|
union_pipelines.clear();
|
|
124275
124732
|
child_pipelines.clear();
|
|
124276
124733
|
child_dependencies.clear();
|
|
124734
|
+
execution_result = PendingExecutionResult::RESULT_NOT_READY;
|
|
124277
124735
|
}
|
|
124278
124736
|
|
|
124279
124737
|
void Executor::AddChildPipeline(Pipeline *current) {
|
|
@@ -124555,10 +125013,11 @@ void Executor::ThrowExceptionInternal() { // LCOV_EXCL_START
|
|
|
124555
125013
|
|
|
124556
125014
|
void Executor::Flush(ThreadContext &tcontext) {
|
|
124557
125015
|
lock_guard<mutex> elock(executor_lock);
|
|
124558
|
-
|
|
125016
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
125017
|
+
profiler.Flush(tcontext.profiler);
|
|
124559
125018
|
}
|
|
124560
125019
|
|
|
124561
|
-
bool Executor::GetPipelinesProgress(
|
|
125020
|
+
bool Executor::GetPipelinesProgress(double ¤t_progress) { // LCOV_EXCL_START
|
|
124562
125021
|
lock_guard<mutex> elock(executor_lock);
|
|
124563
125022
|
|
|
124564
125023
|
if (!pipelines.empty()) {
|
|
@@ -124604,9 +125063,9 @@ ExecutorTask::ExecutorTask(ClientContext &context) : ExecutorTask(Executor::Get(
|
|
|
124604
125063
|
ExecutorTask::~ExecutorTask() {
|
|
124605
125064
|
}
|
|
124606
125065
|
|
|
124607
|
-
|
|
125066
|
+
TaskExecutionResult ExecutorTask::Execute(TaskExecutionMode mode) {
|
|
124608
125067
|
try {
|
|
124609
|
-
ExecuteTask();
|
|
125068
|
+
return ExecuteTask(mode);
|
|
124610
125069
|
} catch (Exception &ex) {
|
|
124611
125070
|
executor.PushError(ex.type, ex.what());
|
|
124612
125071
|
} catch (std::exception &ex) {
|
|
@@ -124614,6 +125073,7 @@ void ExecutorTask::Execute() {
|
|
|
124614
125073
|
} catch (...) { // LCOV_EXCL_START
|
|
124615
125074
|
executor.PushError(ExceptionType::UNKNOWN_TYPE, "Unknown exception in Finalize!");
|
|
124616
125075
|
} // LCOV_EXCL_STOP
|
|
125076
|
+
return TaskExecutionResult::TASK_ERROR;
|
|
124617
125077
|
}
|
|
124618
125078
|
|
|
124619
125079
|
} // namespace duckdb
|
|
@@ -124641,6 +125101,8 @@ void ExecutorTask::Execute() {
|
|
|
124641
125101
|
namespace duckdb {
|
|
124642
125102
|
|
|
124643
125103
|
class PipelineTask : public ExecutorTask {
|
|
125104
|
+
static constexpr const idx_t PARTIAL_CHUNK_COUNT = 50;
|
|
125105
|
+
|
|
124644
125106
|
public:
|
|
124645
125107
|
explicit PipelineTask(Pipeline &pipeline_p, shared_ptr<Event> event_p)
|
|
124646
125108
|
: ExecutorTask(pipeline_p.executor), pipeline(pipeline_p), event(move(event_p)) {
|
|
@@ -124648,12 +125110,24 @@ public:
|
|
|
124648
125110
|
|
|
124649
125111
|
Pipeline &pipeline;
|
|
124650
125112
|
shared_ptr<Event> event;
|
|
125113
|
+
unique_ptr<PipelineExecutor> pipeline_executor;
|
|
124651
125114
|
|
|
124652
125115
|
public:
|
|
124653
|
-
|
|
124654
|
-
|
|
124655
|
-
|
|
125116
|
+
TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override {
|
|
125117
|
+
if (!pipeline_executor) {
|
|
125118
|
+
pipeline_executor = make_unique<PipelineExecutor>(pipeline.GetClientContext(), pipeline);
|
|
125119
|
+
}
|
|
125120
|
+
if (mode == TaskExecutionMode::PROCESS_PARTIAL) {
|
|
125121
|
+
bool finished = pipeline_executor->Execute(PARTIAL_CHUNK_COUNT);
|
|
125122
|
+
if (!finished) {
|
|
125123
|
+
return TaskExecutionResult::TASK_NOT_FINISHED;
|
|
125124
|
+
}
|
|
125125
|
+
} else {
|
|
125126
|
+
pipeline_executor->Execute();
|
|
125127
|
+
}
|
|
124656
125128
|
event->FinishTask();
|
|
125129
|
+
pipeline_executor.reset();
|
|
125130
|
+
return TaskExecutionResult::TASK_FINISHED;
|
|
124657
125131
|
}
|
|
124658
125132
|
};
|
|
124659
125133
|
|
|
@@ -124665,7 +125139,7 @@ ClientContext &Pipeline::GetClientContext() {
|
|
|
124665
125139
|
}
|
|
124666
125140
|
|
|
124667
125141
|
// LCOV_EXCL_START
|
|
124668
|
-
bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op,
|
|
125142
|
+
bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op, double ¤t_percentage) {
|
|
124669
125143
|
current_percentage = -1;
|
|
124670
125144
|
switch (op->type) {
|
|
124671
125145
|
case PhysicalOperatorType::TABLE_SCAN: {
|
|
@@ -124684,7 +125158,7 @@ bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op,
|
|
|
124684
125158
|
}
|
|
124685
125159
|
// LCOV_EXCL_STOP
|
|
124686
125160
|
|
|
124687
|
-
bool Pipeline::GetProgress(
|
|
125161
|
+
bool Pipeline::GetProgress(double ¤t_percentage) {
|
|
124688
125162
|
auto &client = executor.context;
|
|
124689
125163
|
return GetProgressInternal(client, source, current_percentage);
|
|
124690
125164
|
}
|
|
@@ -124885,16 +125359,18 @@ PipelineExecutor::PipelineExecutor(ClientContext &context_p, Pipeline &pipeline_
|
|
|
124885
125359
|
InitializeChunk(final_chunk);
|
|
124886
125360
|
}
|
|
124887
125361
|
|
|
124888
|
-
|
|
125362
|
+
bool PipelineExecutor::Execute(idx_t max_chunks) {
|
|
124889
125363
|
D_ASSERT(pipeline.sink);
|
|
125364
|
+
bool exhausted_source = false;
|
|
124890
125365
|
auto &source_chunk = pipeline.operators.empty() ? final_chunk : *intermediate_chunks[0];
|
|
124891
|
-
|
|
125366
|
+
for (idx_t i = 0; i < max_chunks; i++) {
|
|
124892
125367
|
if (finished_processing) {
|
|
124893
125368
|
break;
|
|
124894
125369
|
}
|
|
124895
125370
|
source_chunk.Reset();
|
|
124896
125371
|
FetchFromSource(source_chunk);
|
|
124897
125372
|
if (source_chunk.size() == 0) {
|
|
125373
|
+
exhausted_source = true;
|
|
124898
125374
|
break;
|
|
124899
125375
|
}
|
|
124900
125376
|
auto result = ExecutePushInternal(source_chunk);
|
|
@@ -124903,7 +125379,15 @@ void PipelineExecutor::Execute() {
|
|
|
124903
125379
|
break;
|
|
124904
125380
|
}
|
|
124905
125381
|
}
|
|
125382
|
+
if (!exhausted_source && !finished_processing) {
|
|
125383
|
+
return false;
|
|
125384
|
+
}
|
|
124906
125385
|
PushFinalize();
|
|
125386
|
+
return true;
|
|
125387
|
+
}
|
|
125388
|
+
|
|
125389
|
+
void PipelineExecutor::Execute() {
|
|
125390
|
+
Execute(NumericLimits<idx_t>::Maximum());
|
|
124907
125391
|
}
|
|
124908
125392
|
|
|
124909
125393
|
OperatorResultType PipelineExecutor::ExecutePush(DataChunk &input) { // LCOV_EXCL_START
|
|
@@ -129434,7 +129918,7 @@ void TaskScheduler::ExecuteForever(atomic<bool> *marker) {
|
|
|
129434
129918
|
// wait for a signal with a timeout; the timeout allows us to periodically check
|
|
129435
129919
|
queue->semaphore.wait(TASK_TIMEOUT_USECS);
|
|
129436
129920
|
if (queue->q.try_dequeue(task)) {
|
|
129437
|
-
task->Execute();
|
|
129921
|
+
task->Execute(TaskExecutionMode::PROCESS_ALL);
|
|
129438
129922
|
task.reset();
|
|
129439
129923
|
}
|
|
129440
129924
|
}
|
|
@@ -129507,7 +129991,7 @@ void TaskScheduler::SetThreadsInternal(int32_t n) {
|
|
|
129507
129991
|
|
|
129508
129992
|
namespace duckdb {
|
|
129509
129993
|
|
|
129510
|
-
ThreadContext::ThreadContext(ClientContext &context) : profiler(context.
|
|
129994
|
+
ThreadContext::ThreadContext(ClientContext &context) : profiler(QueryProfiler::Get(context).IsEnabled()) {
|
|
129511
129995
|
}
|
|
129512
129996
|
|
|
129513
129997
|
} // namespace duckdb
|
|
@@ -154511,13 +154995,15 @@ Planner::Planner(ClientContext &context) : binder(Binder::CreateBinder(context))
|
|
|
154511
154995
|
}
|
|
154512
154996
|
|
|
154513
154997
|
void Planner::CreatePlan(SQLStatement &statement) {
|
|
154998
|
+
auto &profiler = QueryProfiler::Get(context);
|
|
154999
|
+
|
|
154514
155000
|
vector<BoundParameterExpression *> bound_parameters;
|
|
154515
155001
|
|
|
154516
155002
|
// first bind the tables and columns to the catalog
|
|
154517
|
-
|
|
155003
|
+
profiler.StartPhase("binder");
|
|
154518
155004
|
binder->parameters = &bound_parameters;
|
|
154519
155005
|
auto bound_statement = binder->Bind(statement);
|
|
154520
|
-
|
|
155006
|
+
profiler.EndPhase();
|
|
154521
155007
|
|
|
154522
155008
|
this->read_only = binder->read_only;
|
|
154523
155009
|
this->requires_valid_transaction = binder->requires_valid_transaction;
|