Feature: reject partition fullscan as gpcontrib extension#1713
Open
lqriu wants to merge 2 commits intoapache:mainfrom
Open
Feature: reject partition fullscan as gpcontrib extension#1713lqriu wants to merge 2 commits intoapache:mainfrom
lqriu wants to merge 2 commits intoapache:mainfrom
Conversation
Add a planner_hook-based extension under gpcontrib/ that rejects queries on partitioned tables when no effective partition pruning occurs. This keeps all core optimizer files untouched. The extension uses three complementary detection strategies: 1. PartitionPruneInfo check: for Planner Append nodes with pruning conditions and ORCA PartitionSelector nodes. 2. Append heuristic: for Planner Append/MergeAppend without PartitionPruneInfo (no WHERE, WHERE 1=1, non-partition-key WHERE), detected by cross-referencing apprelids with partitioned-table RTEs. 3. DynamicScan check: for ORCA DynamicSeqScan and similar nodes whose part_prune_info is never set by ORCA, detected by comparing partOids count against catalog partition count. New GUC parameters (registered via DefineCustomXxxVariable): - reject_partition_fullscan (bool, default on) - partition_fullscan_threshold (int, default 0) Exemptions: enable_partition_pruning=off, single-partition tables, runtime pruning steps (prepared statements), JOIN dynamic pruning.
yjhjstz
reviewed
May 2, 2026
| gp_toolkit \ | ||
| pg_hint_plan | ||
| pg_hint_plan \ | ||
| reject_partition_fullscan |
Member
There was a problem hiding this comment.
let's set only enable_debug_extensions=yes, enable reject_partition_fullscan extension
Per reviewer feedback, restrict the extension to build only when enable_debug_extensions=yes, rather than in all builds.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Add a
planner_hook-based extension undergpcontrib/that rejects querieson partitioned tables when no effective partition pruning occurs. This prevents
unintended full partition scans in production environments.
This replaces the previous PR #1711, which modified core optimizer files.
Per reviewer feedback, the implementation is now fully self-contained as an
extension with zero core file changes (only
gpcontrib/Makefileis touchedto register the extension in the build).
Architecture
The extension installs a
planner_hookthat wrapsstandard_planner().After the planner (including ORCA) produces a
PlannedStmt, the hook walksthe plan tree using three complementary detection strategies:
Check 1 — PartitionPruneInfo check (Planner + ORCA JOIN path):
For nodes with
part_prune_info != NULL, comparepresent_partsvsnparts.Exempt nodes with
initial_pruning_stepsorexec_pruning_steps(runtimepruning capable, e.g., prepared statements).
Check 2 — Append heuristic (Planner path, no useful pruning quals):
When the standard Planner processes queries with no WHERE, WHERE 1=1, or
WHERE on non-partition-key columns, it does not generate
PartitionPruneInfo.We detect these by checking if
Append.apprelidsreferences a partitionedtable RTE (
relkind='p',inh=true).Check 3 — DynamicScan check (ORCA path):
ORCA never sets
part_prune_infoon DynamicSeqScan nodes. We detect fullscans by comparing
list_length(partOids)against the total partition countfrom
pg_inherits. Nodes withjoin_prune_paramidsare skipped (JOINdynamic pruning).
GUC parameters
reject_partition_fullscan(bool, default ON) — enable/disablepartition_fullscan_threshold(int, default 0) — max partitions allowedafter pruning; 0 means reject only true fullscans
Exemptions
reject_partition_fullscan = offenable_partition_pruning = offError message
Usage
Type of Change
Breaking Changes
When loaded, queries that previously performed full partition scans will
be rejected by default. Users can disable with:
SET reject_partition_fullscan = off;Test Plan
sql/partition_fullscan_reject.sql(12 scenarios)-Werror— zero warnings, zero errorsmake installcheck(full cluster)Impact
plan_tree_walkerafterplanning, added to the existing ~11 post-planning traversals
gpcontrib/Makefilemodified)Compliance Checklist
Files Changed
gpcontrib/Makefilegpcontrib/reject_partition_fullscan/reject_partition_fullscan.cgpcontrib/reject_partition_fullscan/Makefilegpcontrib/reject_partition_fullscan/reject_partition_fullscan.controlgpcontrib/reject_partition_fullscan/reject_partition_fullscan--1.0.sqlgpcontrib/reject_partition_fullscan/sql/partition_fullscan_reject.sql