This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new d340d568362 [opt](build) Enable unity builds for the Exec and Exprs
targets (#66776)
d340d568362 is described below
commit d340d568362887cb21ac79c7a6f20a58ff16513f
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Fri Aug 14 21:41:27 2026 +0800
[opt](build) Enable unity builds for the Exec and Exprs targets (#66776)
> Part of the BE build-time optimization series tracked in #66715.
>
> Split out of **https://github.com/apache/doris/pull/66510**, which
carries the whole
> BE build-time batch. #66712 introduced the `ENABLE_UNITY_BUILD` switch
and piloted
> unity builds on three low-risk glue targets. This PR extends unity to
**Exec and
> Exprs** — the two heaviest targets in the BE build and the largest
single source of
> the unity line's win. The remaining targets follow in one more PR.
### What problem does this PR solve?
Related PR: #66510, #66712
Problem Summary:
Same mechanism as #66712: most of the cold-build cost of glue-heavy
targets is
**re-parsing the shared header closure once per small `.cpp`**, and
CMake's
`UNITY_BUILD` makes a batch pay that parse once. What is new here is the
scale —
Exec (174 TUs, `libExec.a` 2450 MB) and Exprs (287 TUs, `libExprs.a`
2721 MB) are
the two heaviest targets in the tree, and their glue shares the heaviest
closures
(`operator.h`/`dependency.h` for Exec; the vexpr/factory closure for
Exprs).
The four commits:
1. **Deduplicate exec file-scope names that clash under unity** (no
behavior
change): `file_scanner.cpp`/`file_scanner_v2.cpp` both defined the
Iceberg
delete content codes and `is_iceberg_position_deletes_sys_table()` in
anonymous
namespaces — the shared trio moves to `iceberg_scan_semantics.h`
(`file_scanner_v2_test.cpp` carried a third copy, kept file-local by
#66615
because this header move had not landed yet; it now uses the header
too).
`vtablet_writer.cpp`/`vtablet_writer_v2.cpp` both defined a file-scope
`CLOSE_WAIT_EVENT_FALLBACK_MS` — scoped into `IndexChannel` and
`VTabletWriterV2`; v2's file-scope `on_partitions_created()` trampoline
renamed
`on_partitions_created_v2` (the two functions cast to different writer
types).
`exchange_sink_operator.cpp`'s namespace-scope `timer_name` renamed
`wait_for_dependency_timer_name` (shadowed unity siblings' locals under
`-Wshadow -Werror`).
2. **Unity for the whole Exec target**: 167 of 174 TUs join 14 unity
batches of
≤12 sources, gated on `ENABLE_UNITY_BUILD` like the pilot targets. Opted
out:
five files whose file-scope macros must not leak into siblings, plus the
two
heaviest template-instantiation TUs (`operator.cpp`,
`hashjoin_build_sink.cpp`)
which would dominate any batch they join; `scan_operator.cpp` is both.
3. **Three latent defects the Exprs conversion surfaced** (stand on
their own):
`dictionary_factory.h` had **no include guard at all** — any TU reaching
it
through two include paths fails with a class redefinition, and under
unity the
clang error recovery poisoned unrelated batch members with spurious
`-Warray-bounds` diagnostics. Now `#pragma once`. And
`function_dict_get_many.cpp` had copy-pasted the `DictGetState` struct
from
`function_dict_get.cpp` at namespace scope — renamed `DictGetManyState`
so the
two TUs can share a batch. And `function_variant_element_v2.cpp` kept
`OwnedPathSegment` in an anonymous namespace while using it as a field
of the
externally-visible `ResolvedVariantElementV2Path::Impl` — gcc's
`-Wsubobject-linkage` (`-Werror`) rejects exactly that once the file is
`#include`d into a unity batch instead of being the main file of its TU
(clang has no such warning); the struct moves to namespace scope.
4. **Unity for the Exprs glue**: 246 of 287 TUs join 31 unity batches of
≤8
sources, same switch. Opted out: the flex/bison/gperf generated tables,
seven
macro-leaking files, the 30 heavy template-instantiation TUs (>15 s wall
or
>2.2 GB RSS in the compile bench: the min_max/collect/topn/percentile
aggregate
family, `in.cpp`, `multiply.cpp`, `function_array_aggregation.cpp`, …)
whose
per-file codegen would only stack into jumbo poles — and three files
that
tests compile a second time by `#include`ing the `.cpp`
(`function_variant_element.cpp`, `uuid.cpp`,
`function_jsonb_transform.cpp`),
see the verification section.
### Measured results
All numbers from the development branch this series is split from, macOS
arm64 +
clang 20, `-j14`, `ENABLE_PCH=ON`, cold builds, back-to-back A/B. The
baseline is
the #66712 state of that branch (10m16s), so the two waves compose with
the pilot:
| wave | build phase wall | target slot time | archive size |
|---|---|---|---|
| Exec unity | 10m16s → **8m57s (-79.2 s / -12.9%)** | 1533 s → 579 s
(2.6×) | `libExec.a` 2450 MB → 641 MB |
| Exprs unity | 8m57s → **7m57s (-60.0 s / -11.2%)** | 2147 s → 1333 s |
`libExprs.a` 2721 MB → 1392 MB |
Jumbo-TU envelope: the largest Exec unity TU compiles in 32 s / 2.6 GB
RSS
standalone, the largest Exprs one in 25 s / 1.95 GB — both below the
largest
existing individual TU in the tree (3.9 GB), so `-jN` memory envelopes
are
unchanged.
### Risk and verification
- **Unity changes TU grouping only.** The code commits riding along are
hygiene:
constants deduplicated with identical values, one constant scoped into
its class,
two renames, one `#pragma once`. No logic change.
- **Archive symbol parity** (checked on the development branch): Exec
keeps all
external defined symbols — three weak linkonce_odr template
instantiations dedup
away, which is the point of unity, not a loss. Exprs likewise (one weak
instantiation dedups; the `DictGetManyState` rename carries its
`shared_ptr`
machinery under the new name).
- **This exact branch, rebased onto current master, full BE build from
scratch**
(macOS arm64, clang 20, `ENABLE_PCH=ON`, `ENABLE_UNITY_BUILD=ON`):
**7981/7981 ninja edges, zero failures, `doris_be` links (325 MB).**
Exec
produces exactly 14 unity TUs and Exprs exactly 31, as advertised. This
includes
`pipeline/rec_cte_shared_state.cpp`, added upstream after the waves were
measured — it lands inside an Exec unity batch via the existing
`GLOB_RECURSE`
with zero CMakeLists edits, which is the intended maintenance story.
- **The first CI round of this PR did its job and caught two issues;
both are
fixed in the current revision.**
1. *BE UT lane, duplicate symbols at link*: three test files compile a
src
`.cpp` a second time by `#include`ing it
(`function_variant_element_test`,
`function_uuid_test`, `function_json_object_flatten_test`). Pre-unity
this
linked only by archive-member selectivity: the test object defines the
symbols first and the library member is never pulled. A unity batch,
however, is pulled in for its *siblings* and brings a second strong
definition. The three `#include`d files
(`function_variant_element.cpp`, `uuid.cpp`,
`function_jsonb_transform.cpp`)
are now `SKIP_UNITY_BUILD_INCLUSION` — individual archive members
restore
exactly the shadowing semantics master links with today.
2. *Performance lane (the one gcc lane), `-Werror=subobject-linkage`*:
`function_variant_element_v2.cpp` held `OwnedPathSegment` in an
anonymous
namespace as a field type of the externally-visible `...Path::Impl`. gcc
only raises `-Wsubobject-linkage` when the definition sits in an
`#include`d file — which is what unity turns a `.cpp` into; clang has no
such warning, so every local build was green. The struct moves to
namespace scope (name unique to the TU); fixed at the source rather than
SKIPped.
- **The OFF path, checked on the same tree**: reconfiguring with
`ENABLE_UNITY_BUILD=OFF` drops **all 51** `unity_*.cxx` entries from
`compile_commands.json` (Exec 14, Exprs 31, the #66712 pilots 6) and the
TU
count goes 8464 → 9042 — the batches return to exactly their 629 member
files.
Reconfiguring back ON restores exactly the same 51 batches. The switch
semantics themselves (including winning over a stale `CMAKE_UNITY_BUILD`
cache) were established in #66712.
- **These two targets have been building as unity TUs on the development
branch
since 2026-08-08**, through repeated full-tree builds and the BE UT
builds that
verified #66672 (the UT binaries link against these same target
libraries).
- The `file_scanner_v2_test.cpp` hunk was compile-verified standalone
against this
branch (`-fsyntax-only` with the test TU's full include closure).
### Proactive disclosure
- **Cross-platform is the blind spot, closed by this PR's own CI** —
every local
build and measurement above is macOS arm64 + clang 20. With
`ENABLE_UNITY_BUILD`
defaulting ON since #66712, the Linux compile lanes and every regression
pipeline
in this PR's CI run against unity Exec/Exprs — that is the validation,
and the
first round proved it works: the BE UT and gcc lanes each caught one
real
unity interaction (detailed above), fixed in this revision. Escape
hatches, in order:
per-user `ENABLE_UNITY_BUILD=OFF`, per-file
`SKIP_UNITY_BUILD_INCLUSION`, or a
one-line default flip.
- **The incremental-rebuild trade-off is real**: touching one `.cpp`
inside a
batch recompiles the whole batch (≤12 sources for Exec, ≤8 for Exprs; a
batch
compiles in ~25–32 s). This is why the heaviest, most-edited TUs
(`operator.cpp`, `hashjoin_build_sink.cpp`, the aggregate families,
`in.cpp`,
`multiply.cpp`, …) are deliberately SKIPped and keep per-file
granularity, and
`ENABLE_UNITY_BUILD=OFF` restores it everywhere.
- **The SKIP lists are coverage policy, not leftovers**: 7 Exec + 38
Exprs files
stay individual on purpose — generated parsers (flex/bison/gperf), files
whose
file-scope macros would leak into siblings, and the heavy codegen TUs
where
merging saves no closure parse worth the jumbo-TU cost. A future file
whose
file-scope symbols clash inside a unity TU opts out the same one-line
way.
- Unity covers the *glue* of these targets, not the codegen-heavy
families — the
30 heavy Exprs SKIPs mean the headline per-target ratios (2.6× Exec slot
time)
are earned on the batched part; the SKIPped monsters keep their cost and
their
per-file granularity.
---
be/src/exec/CMakeLists.txt | 18 +++++++
be/src/exec/operator/exchange_sink_operator.cpp | 15 +++---
be/src/exec/scan/file_scanner.cpp | 15 +-----
be/src/exec/scan/file_scanner_v2.cpp | 12 -----
be/src/exec/sink/writer/vtablet_writer.cpp | 2 -
be/src/exec/sink/writer/vtablet_writer.h | 2 +
be/src/exec/sink/writer/vtablet_writer_v2.cpp | 6 +--
be/src/exec/sink/writer/vtablet_writer_v2.h | 2 +
be/src/exprs/CMakeLists.txt | 63 ++++++++++++++++++++++
be/src/exprs/function/dictionary_factory.h | 2 +
be/src/exprs/function/function_dict_get_many.cpp | 6 +--
.../exprs/function/function_variant_element_v2.cpp | 7 ++-
be/src/format/table/iceberg_scan_semantics.h | 13 +++++
be/test/exec/scan/file_scanner_v2_test.cpp | 4 +-
14 files changed, 118 insertions(+), 49 deletions(-)
diff --git a/be/src/exec/CMakeLists.txt b/be/src/exec/CMakeLists.txt
index 10f59e25dbb..7ec05378911 100644
--- a/be/src/exec/CMakeLists.txt
+++ b/be/src/exec/CMakeLists.txt
@@ -38,6 +38,24 @@ add_library(Exec STATIC
pch_reuse(Exec)
+# Unity build for the whole Exec target: the operator/sink/scan glue TUs share
+# one heavy (operator.h/dependency.h) header closure, so batching them cuts the
+# repeated frontend work. Batch 12 bounds jumbo-TU size and memory. Opted out:
+# five files whose file-scope macros must not leak into unity siblings, plus
+# the two heaviest template-instantiation TUs which would dominate any batch
+# they join (scan_operator.cpp is both).
+set(EXEC_UNITY_SKIP
+ ${CMAKE_CURRENT_SOURCE_DIR}/common/arrow_column_to_doris_column.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/operator/hashjoin_build_sink.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/operator/join_build_sink_operator.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/operator/operator.cpp
+
${CMAKE_CURRENT_SOURCE_DIR}/operator/partitioned_aggregation_sink_operator.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/operator/scan_operator.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/sink/writer/vfile_result_writer.cpp)
+set_source_files_properties(${EXEC_UNITY_SKIP} PROPERTIES
SKIP_UNITY_BUILD_INCLUSION ON)
+set_target_properties(Exec PROPERTIES UNITY_BUILD ${DORIS_UNITY_BUILD}
+ UNITY_BUILD_BATCH_SIZE 12)
+
if (${BUILD_TASK_EXECUTOR_SIMULATOR} STREQUAL "ON")
file(GLOB_RECURSE SIMULATOR_FILES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/scan/task_executor/tools/simulator/*.cpp"
diff --git a/be/src/exec/operator/exchange_sink_operator.cpp
b/be/src/exec/operator/exchange_sink_operator.cpp
index 2011a44d2ca..3fe4201ad83 100644
--- a/be/src/exec/operator/exchange_sink_operator.cpp
+++ b/be/src/exec/operator/exchange_sink_operator.cpp
@@ -49,7 +49,7 @@ bool ExchangeSinkLocalState::transfer_large_data_by_brpc()
const {
return _parent->cast<ExchangeSinkOperatorX>()._transfer_large_data_by_brpc;
}
-static const std::string timer_name = "WaitForDependencyTime";
+static const std::string wait_for_dependency_timer_name =
"WaitForDependencyTime";
Status ExchangeSinkLocalState::init(RuntimeState* state, LocalSinkStateInfo&
info) {
RETURN_IF_ERROR(Base::init(state, info));
@@ -81,17 +81,18 @@ Status ExchangeSinkLocalState::init(RuntimeState* state,
LocalSinkStateInfo& inf
"");
_merge_block_timer = ADD_TIMER(custom_profile(), "MergeBlockTime");
_local_bytes_send_counter = ADD_COUNTER(custom_profile(),
"LocalBytesSent", TUnit::BYTES);
- _wait_for_dependency_timer = ADD_TIMER_WITH_LEVEL(common_profile(),
timer_name, 1);
- _wait_queue_timer =
- ADD_CHILD_TIMER_WITH_LEVEL(common_profile(),
"WaitForRpcBufferQueue", timer_name, 1);
+ _wait_for_dependency_timer =
+ ADD_TIMER_WITH_LEVEL(common_profile(),
wait_for_dependency_timer_name, 1);
+ _wait_queue_timer = ADD_CHILD_TIMER_WITH_LEVEL(common_profile(),
"WaitForRpcBufferQueue",
+
wait_for_dependency_timer_name, 1);
_create_channels();
// Make sure brpc stub is ready before execution.
for (auto& channel : channels) {
RETURN_IF_ERROR(channel->init(state));
}
- _wait_broadcast_buffer_timer =
- ADD_CHILD_TIMER(common_profile(), "WaitForBroadcastBuffer",
timer_name);
+ _wait_broadcast_buffer_timer = ADD_CHILD_TIMER(common_profile(),
"WaitForBroadcastBuffer",
+
wait_for_dependency_timer_name);
auto& p = _parent->cast<ExchangeSinkOperatorX>();
_part_type = p._part_type;
@@ -262,7 +263,7 @@ Status ExchangeSinkLocalState::open(RuntimeState* state) {
_wait_channel_timer.push_back(common_profile()->add_nonzero_counter(
fmt::format("WaitForLocalExchangeBuffer{}",
_local_channels_dependency.size()),
- TUnit ::TIME_NS, timer_name, 1));
+ TUnit ::TIME_NS, wait_for_dependency_timer_name,
1));
}
}
}
diff --git a/be/src/exec/scan/file_scanner.cpp
b/be/src/exec/scan/file_scanner.cpp
index 6bdf487f204..b262cc6c900 100644
--- a/be/src/exec/scan/file_scanner.cpp
+++ b/be/src/exec/scan/file_scanner.cpp
@@ -71,6 +71,7 @@
#include "format/table/hudi_reader.h"
#include "format/table/iceberg_position_delete_sys_table_reader.h"
#include "format/table/iceberg_reader.h"
+#include "format/table/iceberg_scan_semantics.h"
#include "format/table/iceberg_sys_table_jni_reader.h"
#include "format/table/jdbc_jni_reader.h"
#include "format/table/max_compute_jni_reader.h"
@@ -100,20 +101,6 @@ class ShardedKVCache;
namespace doris {
using namespace ErrorCode;
-namespace {
-constexpr int kIcebergPositionDeleteContent = 1;
-constexpr int kIcebergDeletionVectorContent = 3;
-
-bool is_iceberg_position_deletes_sys_table(const TFileRangeDesc& range) {
- return range.__isset.table_format_params &&
- range.table_format_params.table_format_type == "iceberg" &&
- range.table_format_params.__isset.iceberg_params &&
- range.table_format_params.iceberg_params.__isset.content &&
- (range.table_format_params.iceberg_params.content ==
kIcebergPositionDeleteContent ||
- range.table_format_params.iceberg_params.content ==
kIcebergDeletionVectorContent);
-}
-} // namespace
-
const std::string FileScanner::FileReadBytesProfile = "FileReadBytes";
const std::string FileScanner::FileReadTimeProfile = "FileReadTime";
diff --git a/be/src/exec/scan/file_scanner_v2.cpp
b/be/src/exec/scan/file_scanner_v2.cpp
index 420bbd62a42..23f55c421fc 100644
--- a/be/src/exec/scan/file_scanner_v2.cpp
+++ b/be/src/exec/scan/file_scanner_v2.cpp
@@ -76,9 +76,6 @@
namespace doris {
namespace {
-constexpr int kIcebergPositionDeleteContent = 1;
-constexpr int kIcebergDeletionVectorContent = 3;
-
std::string table_format_name(const TFileRangeDesc& range) {
return range.__isset.table_format_params ?
range.table_format_params.table_format_type
: "NotSet";
@@ -136,15 +133,6 @@ bool is_supported_jni_table_format(const TFileRangeDesc&
range) {
table_format == "max_compute" || table_format == "trino_connector";
}
-bool is_iceberg_position_deletes_sys_table(const TFileRangeDesc& range) {
- return range.__isset.table_format_params &&
- range.table_format_params.table_format_type == "iceberg" &&
- range.table_format_params.__isset.iceberg_params &&
- range.table_format_params.iceberg_params.__isset.content &&
- (range.table_format_params.iceberg_params.content ==
kIcebergPositionDeleteContent ||
- range.table_format_params.iceberg_params.content ==
kIcebergDeletionVectorContent);
-}
-
bool is_csv_format(TFileFormatType::type format_type) {
switch (format_type) {
case TFileFormatType::FORMAT_CSV_PLAIN:
diff --git a/be/src/exec/sink/writer/vtablet_writer.cpp
b/be/src/exec/sink/writer/vtablet_writer.cpp
index dcdfe55136f..e1a3a29914d 100644
--- a/be/src/exec/sink/writer/vtablet_writer.cpp
+++ b/be/src/exec/sink/writer/vtablet_writer.cpp
@@ -127,8 +127,6 @@ static const std::vector<int32_t>&
adaptive_local_bucket_seqs(const VOlapTablePa
return partition.local_bucket_seqs;
}
-static constexpr int64_t CLOSE_WAIT_EVENT_FALLBACK_MS = 1000;
-
Status IndexChannel::init(RuntimeState* state, const
std::vector<TTabletWithPartition>& tablets,
bool incremental) {
SCOPED_CONSUME_MEM_TRACKER(_index_channel_tracker.get());
diff --git a/be/src/exec/sink/writer/vtablet_writer.h
b/be/src/exec/sink/writer/vtablet_writer.h
index 6b9b8c3d787..1605faba306 100644
--- a/be/src/exec/sink/writer/vtablet_writer.h
+++ b/be/src/exec/sink/writer/vtablet_writer.h
@@ -583,6 +583,8 @@ private:
friend class VTabletWriter;
friend class VRowDistribution;
+ static constexpr int64_t CLOSE_WAIT_EVENT_FALLBACK_MS = 1000;
+
int _max_failed_replicas(int64_t tablet_id);
int _load_required_replicas_num(int64_t tablet_id);
diff --git a/be/src/exec/sink/writer/vtablet_writer_v2.cpp
b/be/src/exec/sink/writer/vtablet_writer_v2.cpp
index 1b790f966ae..8a5fe58500a 100644
--- a/be/src/exec/sink/writer/vtablet_writer_v2.cpp
+++ b/be/src/exec/sink/writer/vtablet_writer_v2.cpp
@@ -60,8 +60,6 @@ namespace doris {
extern bvar::Adder<int64_t> g_sink_load_back_pressure_version_time_ms;
-static constexpr int64_t CLOSE_WAIT_EVENT_FALLBACK_MS = 1000;
-
VTabletWriterV2::VTabletWriterV2(const TDataSink& t_sink, const
VExprContextSPtrs& output_exprs,
std::shared_ptr<Dependency> dep,
std::shared_ptr<Dependency> fin_dep)
@@ -85,7 +83,7 @@ Status
VTabletWriterV2::on_partitions_created(TCreatePartitionResult* result) {
return Status::OK();
}
-static Status on_partitions_created(void* writer, TCreatePartitionResult*
result) {
+static Status on_partitions_created_v2(void* writer, TCreatePartitionResult*
result) {
return
static_cast<VTabletWriterV2*>(writer)->on_partitions_created(result);
}
@@ -139,7 +137,7 @@ Status VTabletWriterV2::_init_row_distribution() {
.vec_output_expr_ctxs = &_vec_output_expr_ctxs,
.schema = _schema,
.caller = (void*)this,
- .create_partition_callback =
&::doris::on_partitions_created});
+ .create_partition_callback =
&::doris::on_partitions_created_v2});
return _row_distribution.open(_output_row_desc);
}
diff --git a/be/src/exec/sink/writer/vtablet_writer_v2.h
b/be/src/exec/sink/writer/vtablet_writer_v2.h
index 19ae8854bf8..a3d86a613bb 100644
--- a/be/src/exec/sink/writer/vtablet_writer_v2.h
+++ b/be/src/exec/sink/writer/vtablet_writer_v2.h
@@ -118,6 +118,8 @@ private:
std::shared_ptr<LoadStreamMap> load_stream_map);
private:
+ static constexpr int64_t CLOSE_WAIT_EVENT_FALLBACK_MS = 1000;
+
Status _init_row_distribution();
Status _init(RuntimeState* state, RuntimeProfile* profile);
diff --git a/be/src/exprs/CMakeLists.txt b/be/src/exprs/CMakeLists.txt
index 62cc03b4c5c..b7bf6916a90 100644
--- a/be/src/exprs/CMakeLists.txt
+++ b/be/src/exprs/CMakeLists.txt
@@ -38,6 +38,69 @@ target_link_libraries(Exprs
pch_reuse(Exprs)
+# Unity build for the Exprs glue: ~250 registration/wrapper TUs share the
+# vexpr/factory header closure. Batch 8 bounds jumbo-TU size and memory.
+# Opted out and kept as individual TUs:
+# - the flex/bison outputs and tldLookup.generated.cpp (generated tables and
+# macros would clash),
+# - files whose file-scope macros must not leak into unity siblings
+# (fmod_fast, function_bitmap_variadic,
function_date_or_datetime_computation,
+# function_datetime_floor_ceil, function_string_misc, json_functions,
+# math_functions),
+# - the heavy template-instantiation TUs (>15s wall or >2.2GB RSS in the
+# compile bench: the min_max/collect/topn/percentile aggregate family,
+# in.cpp, multiply.cpp, round.cpp, function_array_aggregation.cpp, ...);
+# their codegen is per-file and would only stack into jumbo poles,
+# - files that tests compile a second time by #including the .cpp
+# (function_variant_element, uuid, function_jsonb_transform): the test
+# object must shadow a never-pulled archive member, but a unity batch is
+# pulled in for its siblings and the linker sees a duplicate definition.
+set(EXPRS_UNITY_SKIP
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_array_agg.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_avg.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_bit.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_collect_limit.cpp
+
${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_collect_no_limit.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_distinct.cpp
+
${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_group_array_intersect.cpp
+
${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_group_array_union.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_histogram.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_map_combinator.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_min_max_any.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_min_max_by.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_min_max_max.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_min_max_min.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_percentile.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_reader.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_sum.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_topn_array.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_topn_weighted.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/aggregate/aggregate_function_uniq.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/ai/ai_functions.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/array/function_array_aggregation.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/cast/function_cast_decimal.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/fmod_fast.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/function_bitmap_variadic.cpp
+
${CMAKE_CURRENT_SOURCE_DIR}/function/function_date_or_datetime_computation.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/function_datetime_floor_ceil.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/function_jsonb_transform.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/function_string_misc.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/function_variant_element.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/in.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/minus.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/multiply.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/plus.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/round.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/url/tldLookup.generated.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/function/uuid.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/json_functions.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/math_functions.cpp
+ ${GENSRC_DIR}/geo/wkt_lex.l.cpp
+ ${GENSRC_DIR}/geo/wkt_yacc.y.cpp)
+set_source_files_properties(${EXPRS_UNITY_SKIP} PROPERTIES
SKIP_UNITY_BUILD_INCLUSION ON)
+set_target_properties(Exprs PROPERTIES UNITY_BUILD ${DORIS_UNITY_BUILD}
+ UNITY_BUILD_BATCH_SIZE 8)
+
# Flex/Bison generation rules for geo WKT parsing
add_custom_command(
OUTPUT ${GENSRC_DIR}/geo/wkt_lex.l.cpp ${GENSRC_DIR}/geo/wkt_lex.l.h
diff --git a/be/src/exprs/function/dictionary_factory.h
b/be/src/exprs/function/dictionary_factory.h
index bab27987bf3..5d0630d5974 100644
--- a/be/src/exprs/function/dictionary_factory.h
+++ b/be/src/exprs/function/dictionary_factory.h
@@ -15,6 +15,8 @@
// specific language governing permissions and limitations
// under the License.
+#pragma once
+
#include <gen_cpp/BackendService_types.h>
#include <mutex>
diff --git a/be/src/exprs/function/function_dict_get_many.cpp
b/be/src/exprs/function/function_dict_get_many.cpp
index 93e1f9fae5d..9d06fb5b6db 100644
--- a/be/src/exprs/function/function_dict_get_many.cpp
+++ b/be/src/exprs/function/function_dict_get_many.cpp
@@ -35,7 +35,7 @@
namespace doris {
-struct DictGetState {
+struct DictGetManyState {
std::shared_ptr<const IDictionary> dict;
///TODO:
// 1. we do not need to check dict every time(shoud only check in open)
@@ -65,7 +65,7 @@ public:
if (scope == FunctionContext::THREAD_LOCAL) {
return Status::OK();
}
- std::shared_ptr<DictGetState> state = std::make_shared<DictGetState>();
+ std::shared_ptr<DictGetManyState> state =
std::make_shared<DictGetManyState>();
context->set_function_state(scope, state);
DCHECK(context->get_num_args() == 3);
auto dict_fn = context->dict_function();
@@ -87,7 +87,7 @@ public:
Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
uint32_t result, size_t input_rows_count) const
override {
- auto* dict_state = reinterpret_cast<DictGetState*>(
+ auto* dict_state = reinterpret_cast<DictGetManyState*>(
context->get_function_state(FunctionContext::FRAGMENT_LOCAL));
if (!dict_state) {
return Status::RuntimeError("funciton context for function '{}'
must have dict_state;",
diff --git a/be/src/exprs/function/function_variant_element_v2.cpp
b/be/src/exprs/function/function_variant_element_v2.cpp
index 644a033f4af..9bfd5dea113 100644
--- a/be/src/exprs/function/function_variant_element_v2.cpp
+++ b/be/src/exprs/function/function_variant_element_v2.cpp
@@ -32,16 +32,15 @@
namespace doris {
-namespace {
-
+// Not in the anonymous namespace: as a field of the externally-visible Impl,
an
+// internal-linkage type trips gcc's -Wsubobject-linkage once this file is
+// #included into a unity batch instead of being the main file of its TU.
struct OwnedPathSegment {
VariantElementV2PathSegment::Kind kind;
PaddedPODArray<char> key;
int64_t index = 0;
};
-} // namespace
-
struct ResolvedVariantElementV2Path::Impl {
DorisVector<OwnedPathSegment> segments;
};
diff --git a/be/src/format/table/iceberg_scan_semantics.h
b/be/src/format/table/iceberg_scan_semantics.h
index c708a3d6222..274da536649 100644
--- a/be/src/format/table/iceberg_scan_semantics.h
+++ b/be/src/format/table/iceberg_scan_semantics.h
@@ -36,4 +36,17 @@ inline bool supports_iceberg_scan_semantics_v2(const
TFileScanRangeParams* param
params->iceberg_scan_semantics_version >=
ICEBERG_SCAN_SEMANTICS_VERSION_2;
}
+// Iceberg manifest-entry content codes (spec: 1 = position deletes, 3 =
deletion vectors).
+inline constexpr int kIcebergPositionDeleteContent = 1;
+inline constexpr int kIcebergDeletionVectorContent = 3;
+
+inline bool is_iceberg_position_deletes_sys_table(const TFileRangeDesc& range)
{
+ return range.__isset.table_format_params &&
+ range.table_format_params.table_format_type == "iceberg" &&
+ range.table_format_params.__isset.iceberg_params &&
+ range.table_format_params.iceberg_params.__isset.content &&
+ (range.table_format_params.iceberg_params.content ==
kIcebergPositionDeleteContent ||
+ range.table_format_params.iceberg_params.content ==
kIcebergDeletionVectorContent);
+}
+
} // namespace doris
diff --git a/be/test/exec/scan/file_scanner_v2_test.cpp
b/be/test/exec/scan/file_scanner_v2_test.cpp
index 353c08043ad..328b0e9c33e 100644
--- a/be/test/exec/scan/file_scanner_v2_test.cpp
+++ b/be/test/exec/scan/file_scanner_v2_test.cpp
@@ -46,15 +46,13 @@
#include "exprs/vdirect_in_predicate.h"
#include "exprs/vliteral.h"
#include "exprs/vslot_ref.h"
+#include "format/table/iceberg_scan_semantics.h"
#include "format_v2/expr/cast.h"
#include "testutil/mock/mock_runtime_state.h"
namespace doris {
namespace {
-constexpr int kIcebergPositionDeleteContent = 1;
-constexpr int kIcebergDeletionVectorContent = 3;
-
TFileRangeDesc range_with_format(std::string table_format,
TFileFormatType::type format_type) {
TFileRangeDesc range;
range.__set_format_type(format_type);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]