Coverage Report

Created: 2025-11-01 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/duckdb/src/execution/physical_plan_generator.cpp
Line
Count
Source
1
#include "duckdb/execution/physical_plan_generator.hpp"
2
3
#include "duckdb/catalog/catalog_entry/scalar_function_catalog_entry.hpp"
4
#include "duckdb/common/types/column/column_data_collection.hpp"
5
#include "duckdb/execution/column_binding_resolver.hpp"
6
#include "duckdb/main/client_context.hpp"
7
#include "duckdb/main/config.hpp"
8
#include "duckdb/main/query_profiler.hpp"
9
#include "duckdb/planner/expression/bound_function_expression.hpp"
10
#include "duckdb/planner/operator/logical_extension_operator.hpp"
11
#include "duckdb/planner/operator/list.hpp"
12
#include "duckdb/execution/operator/helper/physical_verify_vector.hpp"
13
#include "duckdb/main/settings.hpp"
14
15
namespace duckdb {
16
17
85.8k
PhysicalPlanGenerator::PhysicalPlanGenerator(ClientContext &context) : context(context) {
18
85.8k
}
19
20
85.8k
PhysicalPlanGenerator::~PhysicalPlanGenerator() {
21
85.8k
}
22
23
83.5k
unique_ptr<PhysicalPlan> PhysicalPlanGenerator::Plan(unique_ptr<LogicalOperator> op) {
24
83.5k
  auto &plan = ResolveAndPlan(std::move(op));
25
83.5k
  plan.Verify();
26
83.5k
  return std::move(physical_plan);
27
83.5k
}
28
29
83.5k
PhysicalOperator &PhysicalPlanGenerator::ResolveAndPlan(unique_ptr<LogicalOperator> op) {
30
83.5k
  auto &profiler = QueryProfiler::Get(context);
31
32
  // Resolve the types of each operator.
33
83.5k
  profiler.StartPhase(MetricsType::PHYSICAL_PLANNER_RESOLVE_TYPES);
34
83.5k
  op->ResolveOperatorTypes();
35
83.5k
  profiler.EndPhase();
36
37
  // Resolve the column references.
38
83.5k
  profiler.StartPhase(MetricsType::PHYSICAL_PLANNER_COLUMN_BINDING);
39
83.5k
  ColumnBindingResolver resolver;
40
83.5k
  resolver.VisitOperator(*op);
41
83.5k
  profiler.EndPhase();
42
43
  // Create the main physical plan.
44
83.5k
  profiler.StartPhase(MetricsType::PHYSICAL_PLANNER_CREATE_PLAN);
45
83.5k
  physical_plan = PlanInternal(*op);
46
83.5k
  profiler.EndPhase();
47
48
  // Return a reference to the root of this plan.
49
83.5k
  return physical_plan->Root();
50
83.5k
}
51
52
85.8k
unique_ptr<PhysicalPlan> PhysicalPlanGenerator::PlanInternal(LogicalOperator &op) {
53
85.8k
  if (!physical_plan) {
54
85.8k
    physical_plan = make_uniq<PhysicalPlan>(Allocator::Get(context));
55
85.8k
  }
56
85.8k
  op.estimated_cardinality = op.EstimateCardinality(context);
57
85.8k
  physical_plan->SetRoot(CreatePlan(op));
58
85.8k
  physical_plan->Root().estimated_cardinality = op.estimated_cardinality;
59
60
85.8k
  auto debug_verify_vector = DBConfig::GetSetting<DebugVerifyVectorSetting>(context);
61
85.8k
  if (debug_verify_vector != DebugVectorVerification::NONE) {
62
0
    if (debug_verify_vector != DebugVectorVerification::DICTIONARY_EXPRESSION &&
63
0
        debug_verify_vector != DebugVectorVerification::VARIANT_VECTOR) {
64
0
      physical_plan->SetRoot(Make<PhysicalVerifyVector>(physical_plan->Root(), debug_verify_vector));
65
0
    }
66
0
  }
67
85.8k
  return std::move(physical_plan);
68
85.8k
}
69
70
637k
PhysicalOperator &PhysicalPlanGenerator::CreatePlan(LogicalOperator &op) {
71
637k
  switch (op.type) {
72
61.2k
  case LogicalOperatorType::LOGICAL_GET:
73
61.2k
    return CreatePlan(op.Cast<LogicalGet>());
74
222k
  case LogicalOperatorType::LOGICAL_PROJECTION:
75
222k
    return CreatePlan(op.Cast<LogicalProjection>());
76
27
  case LogicalOperatorType::LOGICAL_EMPTY_RESULT:
77
27
    return CreatePlan(op.Cast<LogicalEmptyResult>());
78
60.6k
  case LogicalOperatorType::LOGICAL_FILTER:
79
60.6k
    return CreatePlan(op.Cast<LogicalFilter>());
80
44.7k
  case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY:
81
44.7k
    return CreatePlan(op.Cast<LogicalAggregate>());
82
16
  case LogicalOperatorType::LOGICAL_WINDOW:
83
16
    return CreatePlan(op.Cast<LogicalWindow>());
84
1.53k
  case LogicalOperatorType::LOGICAL_UNNEST:
85
1.53k
    return CreatePlan(op.Cast<LogicalUnnest>());
86
156
  case LogicalOperatorType::LOGICAL_LIMIT:
87
156
    return CreatePlan(op.Cast<LogicalLimit>());
88
0
  case LogicalOperatorType::LOGICAL_SAMPLE:
89
0
    return CreatePlan(op.Cast<LogicalSample>());
90
16.0k
  case LogicalOperatorType::LOGICAL_ORDER_BY:
91
16.0k
    return CreatePlan(op.Cast<LogicalOrder>());
92
0
  case LogicalOperatorType::LOGICAL_TOP_N:
93
0
    return CreatePlan(op.Cast<LogicalTopN>());
94
0
  case LogicalOperatorType::LOGICAL_COPY_TO_FILE:
95
0
    return CreatePlan(op.Cast<LogicalCopyToFile>());
96
59.2k
  case LogicalOperatorType::LOGICAL_DUMMY_SCAN:
97
59.2k
    return CreatePlan(op.Cast<LogicalDummyScan>());
98
0
  case LogicalOperatorType::LOGICAL_ANY_JOIN:
99
0
    return CreatePlan(op.Cast<LogicalAnyJoin>());
100
0
  case LogicalOperatorType::LOGICAL_ASOF_JOIN:
101
0
  case LogicalOperatorType::LOGICAL_DELIM_JOIN:
102
29.4k
  case LogicalOperatorType::LOGICAL_COMPARISON_JOIN:
103
29.4k
    return CreatePlan(op.Cast<LogicalComparisonJoin>());
104
36.8k
  case LogicalOperatorType::LOGICAL_CROSS_PRODUCT:
105
36.8k
    return CreatePlan(op.Cast<LogicalCrossProduct>());
106
0
  case LogicalOperatorType::LOGICAL_POSITIONAL_JOIN:
107
0
    return CreatePlan(op.Cast<LogicalPositionalJoin>());
108
17.3k
  case LogicalOperatorType::LOGICAL_UNION:
109
22.9k
  case LogicalOperatorType::LOGICAL_EXCEPT:
110
22.9k
  case LogicalOperatorType::LOGICAL_INTERSECT:
111
22.9k
    return CreatePlan(op.Cast<LogicalSetOperation>());
112
0
  case LogicalOperatorType::LOGICAL_INSERT:
113
0
    return CreatePlan(op.Cast<LogicalInsert>());
114
0
  case LogicalOperatorType::LOGICAL_DELETE:
115
0
    return CreatePlan(op.Cast<LogicalDelete>());
116
377
  case LogicalOperatorType::LOGICAL_CHUNK_GET:
117
377
    return CreatePlan(op.Cast<LogicalColumnDataGet>());
118
0
  case LogicalOperatorType::LOGICAL_DELIM_GET:
119
0
    return CreatePlan(op.Cast<LogicalDelimGet>());
120
16
  case LogicalOperatorType::LOGICAL_EXPRESSION_GET:
121
16
    return CreatePlan(op.Cast<LogicalExpressionGet>());
122
0
  case LogicalOperatorType::LOGICAL_UPDATE:
123
0
    return CreatePlan(op.Cast<LogicalUpdate>());
124
0
  case LogicalOperatorType::LOGICAL_MERGE_INTO:
125
0
    return CreatePlan(op.Cast<LogicalMergeInto>());
126
200
  case LogicalOperatorType::LOGICAL_CREATE_TABLE:
127
200
    return CreatePlan(op.Cast<LogicalCreateTable>());
128
0
  case LogicalOperatorType::LOGICAL_CREATE_INDEX:
129
0
    return CreatePlan(op.Cast<LogicalCreateIndex>());
130
0
  case LogicalOperatorType::LOGICAL_CREATE_SECRET:
131
0
    return CreatePlan(op.Cast<LogicalCreateSecret>());
132
5.22k
  case LogicalOperatorType::LOGICAL_EXPLAIN:
133
5.22k
    return CreatePlan(op.Cast<LogicalExplain>());
134
24
  case LogicalOperatorType::LOGICAL_DISTINCT:
135
24
    return CreatePlan(op.Cast<LogicalDistinct>());
136
4.90k
  case LogicalOperatorType::LOGICAL_PREPARE:
137
4.90k
    return CreatePlan(op.Cast<LogicalPrepare>());
138
4.82k
  case LogicalOperatorType::LOGICAL_EXECUTE:
139
4.82k
    return CreatePlan(op.Cast<LogicalExecute>());
140
0
  case LogicalOperatorType::LOGICAL_CREATE_VIEW:
141
10
  case LogicalOperatorType::LOGICAL_CREATE_SEQUENCE:
142
53
  case LogicalOperatorType::LOGICAL_CREATE_SCHEMA:
143
53
  case LogicalOperatorType::LOGICAL_CREATE_MACRO:
144
53
  case LogicalOperatorType::LOGICAL_CREATE_TYPE:
145
53
    return CreatePlan(op.Cast<LogicalCreate>());
146
9.43k
  case LogicalOperatorType::LOGICAL_PRAGMA:
147
9.43k
    return CreatePlan(op.Cast<LogicalPragma>());
148
21
  case LogicalOperatorType::LOGICAL_VACUUM:
149
21
    return CreatePlan(op.Cast<LogicalVacuum>());
150
18.8k
  case LogicalOperatorType::LOGICAL_TRANSACTION:
151
18.8k
  case LogicalOperatorType::LOGICAL_ALTER:
152
23.8k
  case LogicalOperatorType::LOGICAL_DROP:
153
23.8k
  case LogicalOperatorType::LOGICAL_LOAD:
154
23.8k
  case LogicalOperatorType::LOGICAL_ATTACH:
155
23.8k
  case LogicalOperatorType::LOGICAL_DETACH:
156
23.8k
    return CreatePlan(op.Cast<LogicalSimple>());
157
0
  case LogicalOperatorType::LOGICAL_RECURSIVE_CTE:
158
0
    return CreatePlan(op.Cast<LogicalRecursiveCTE>());
159
1.67k
  case LogicalOperatorType::LOGICAL_MATERIALIZED_CTE:
160
1.67k
    return CreatePlan(op.Cast<LogicalMaterializedCTE>());
161
31.3k
  case LogicalOperatorType::LOGICAL_CTE_REF:
162
31.3k
    return CreatePlan(op.Cast<LogicalCTERef>());
163
0
  case LogicalOperatorType::LOGICAL_EXPORT:
164
0
    return CreatePlan(op.Cast<LogicalExport>());
165
197
  case LogicalOperatorType::LOGICAL_SET:
166
197
    return CreatePlan(op.Cast<LogicalSet>());
167
60
  case LogicalOperatorType::LOGICAL_RESET:
168
60
    return CreatePlan(op.Cast<LogicalReset>());
169
0
  case LogicalOperatorType::LOGICAL_PIVOT:
170
0
    return CreatePlan(op.Cast<LogicalPivot>());
171
0
  case LogicalOperatorType::LOGICAL_COPY_DATABASE:
172
0
    return CreatePlan(op.Cast<LogicalCopyDatabase>());
173
0
  case LogicalOperatorType::LOGICAL_UPDATE_EXTENSIONS:
174
0
    return CreatePlan(op.Cast<LogicalSimple>());
175
0
  case LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR: {
176
0
    auto &extension_op = op.Cast<LogicalExtensionOperator>();
177
0
    return extension_op.CreatePlan(context, *this);
178
23.8k
  }
179
0
  case LogicalOperatorType::LOGICAL_JOIN:
180
0
  case LogicalOperatorType::LOGICAL_DEPENDENT_JOIN:
181
0
  case LogicalOperatorType::LOGICAL_INVALID: {
182
0
    throw NotImplementedException("Unimplemented logical operator type!");
183
0
  }
184
637k
  }
185
0
  throw InternalException("Physical plan generator - no plan generated");
186
637k
}
187
188
} // namespace duckdb