Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Planner/Planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ namespace DB
{
namespace Setting
{
extern const SettingsMap additional_table_filters;
extern const SettingsUInt64 aggregation_in_order_max_block_bytes;
extern const SettingsUInt64 aggregation_memory_efficient_merge_threads;
extern const SettingsUInt64 allow_experimental_parallel_reading_from_replicas;
Expand Down Expand Up @@ -1571,6 +1572,26 @@ void Planner::buildPlanForQueryNode()
}
}

/// `additional_table_filters` keys are resolved against the initiator's session current database,
/// but on followers the rewritten `SELECT` uses fully qualified names and the follower's current
/// database is the initiator's user-default DB, so the filter match is unreliable. Rather than
/// patch the match (which differs case by case), disable the combination on the analyzer path.
/// Upstream `serialize_query_plan=1` is exempt because the initiator lowers the filter into an
/// explicit `FilterStep` and ships the serialized plan, but in 25.8 parallel-replicas followers
/// always receive the rewritten AST (see ReadFromParallelRemoteReplicasStep), so the setting
/// does not help here and the check applies unconditionally.
if (query_context->canUseParallelReplicasOnInitiator()
&& !settings[Setting::additional_table_filters].value.empty())
{
if (settings[Setting::allow_experimental_parallel_reading_from_replicas] >= 2)
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED,
"additional_table_filters is not supported with parallel replicas");

auto & mutable_context = planner_context->getMutableQueryContext();
mutable_context->setSetting("allow_experimental_parallel_reading_from_replicas", Field(0));
LOG_DEBUG(log, "Disabling parallel replicas to execute a query with additional_table_filters");
}

collectTableExpressionData(query_tree, planner_context);
checkStoragesSupportTransactions(planner_context);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
3
3
63 changes: 63 additions & 0 deletions tests/queries/0_stateless/04207_pr_additional_filters.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
-- Tags: no-parallel
-- ^ failpoint

DROP TABLE IF EXISTS atf_p;
CREATE TABLE atf_p (x UInt64) ENGINE = MergeTree ORDER BY tuple();
INSERT INTO atf_p SELECT number FROM numbers(10);

-- The failpoint disables cancellation of unused replicas after all ranges
-- are assigned, so every replica's contribution lands on the initiator and any
-- missing-filter regression is deterministic regardless of timing.

-- `additional_table_filters` keys are resolved against the initiator's session current
-- database, so they cannot be reliably matched on parallel-replica followers (the
-- rewritten query qualifies the table and the follower's current database differs).
-- On the legacy AST-forwarding path the analyzer rejects the combination instead of
-- silently dropping the filter.
SYSTEM ENABLE FAILPOINT parallel_replicas_wait_for_unused_replicas;
SELECT count() FROM atf_p SETTINGS additional_table_filters = {'atf_p': 'x <= 2'},
enable_analyzer = 1,
enable_parallel_replicas = 2,
max_parallel_replicas = 3,
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost',
parallel_replicas_for_non_replicated_merge_tree = 1,
parallel_replicas_local_plan = 1,
serialize_query_plan = 0; -- { serverError SUPPORT_IS_DISABLED }

SELECT count() FROM atf_p SETTINGS additional_table_filters = {'atf_p': 'x <= 2'},
enable_analyzer = 0,
enable_parallel_replicas = 2,
max_parallel_replicas = 3,
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost',
parallel_replicas_for_non_replicated_merge_tree = 1,
parallel_replicas_local_plan = 1,
serialize_query_plan = 0;

-- With `enable_parallel_replicas = 1` (best-effort) parallel replicas is silently
-- disabled and the query runs locally with the filter applied.
SYSTEM ENABLE FAILPOINT parallel_replicas_wait_for_unused_replicas;
SELECT count() FROM atf_p SETTINGS additional_table_filters = {'atf_p': 'x <= 2'},
enable_analyzer = 1,
enable_parallel_replicas = 1,
max_parallel_replicas = 3,
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost',
parallel_replicas_for_non_replicated_merge_tree = 1,
parallel_replicas_local_plan = 1,
serialize_query_plan = 0;

-- Upstream `serialize_query_plan = 1` makes the combination work (the initiator lowers the
-- additional filter into an explicit `FilterStep` and ships the serialized plan), but in 25.8
-- parallel-replicas followers always receive the rewritten AST, so the setting does not help
-- and the combination is rejected as well.
SYSTEM ENABLE FAILPOINT parallel_replicas_wait_for_unused_replicas;
SELECT count() FROM atf_p SETTINGS additional_table_filters = {'atf_p': 'x <= 2'},
enable_analyzer = 1,
enable_parallel_replicas = 2,
max_parallel_replicas = 3,
cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost',
parallel_replicas_for_non_replicated_merge_tree = 1,
parallel_replicas_local_plan = 1,
serialize_query_plan = 1; -- { serverError SUPPORT_IS_DISABLED }

SYSTEM DISABLE FAILPOINT parallel_replicas_wait_for_unused_replicas;
DROP TABLE atf_p;
Loading