lqriu opened a new pull request, #1713:
URL: https://github.com/apache/cloudberry/pull/1713

   ## What does this PR do?
   
   Add a `planner_hook`-based extension under `gpcontrib/` that rejects queries
   on 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/Makefile` is 
touched
   to register the extension in the build).
   
   ### Architecture
   
   The extension installs a `planner_hook` that wraps `standard_planner()`.
   After the planner (including ORCA) produces a `PlannedStmt`, the hook walks
   the plan tree using three complementary detection strategies:
   
   **Check 1 — PartitionPruneInfo check** (Planner + ORCA JOIN path):
   For nodes with `part_prune_info != NULL`, compare `present_parts` vs 
`nparts`.
   Exempt nodes with `initial_pruning_steps` or `exec_pruning_steps` (runtime
   pruning 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.apprelids` references a partitioned
   table RTE (`relkind='p'`, `inh=true`).
   
   **Check 3 — DynamicScan check** (ORCA path):
   ORCA never sets `part_prune_info` on DynamicSeqScan nodes. We detect full
   scans by comparing `list_length(partOids)` against the total partition count
   from `pg_inherits`. Nodes with `join_prune_paramids` are skipped (JOIN
   dynamic pruning).
   
   ### GUC parameters
   - `reject_partition_fullscan` (bool, default ON) — enable/disable
   - `partition_fullscan_threshold` (int, default 0) — max partitions allowed
     after pruning; 0 means reject only true fullscans
   
   ### Exemptions
   | Scenario | Behavior |
   |----------|----------|
   | `reject_partition_fullscan = off` | Allowed |
   | `enable_partition_pruning = off` | Allowed |
   | Single-partition table (nparts <= 1) | Allowed |
   | Runtime pruning steps present (prepared stmt) | Allowed |
   | JOIN dynamic pruning (PartitionSelector / join_prune_paramids) | Allowed |
   | No WHERE / WHERE 1=1 | **Rejected** |
   | WHERE on non-partition-key column | **Rejected** |
   
   ### Error message
   ```
   ERROR: partitioned table "schema.table" full partition scan is not
          allowed, N partitions would be scanned
   HINT:  Add a WHERE clause on the partition key to enable partition pruning.
   ```
   
   ### Usage
   ```sql
   -- Via shared_preload_libraries (recommended for production)
   -- postgresql.conf: shared_preload_libraries = 'reject_partition_fullscan'
   
   -- Or per-session via LOAD
   LOAD 'reject_partition_fullscan';
   ```
   
   ## Type of Change
   - [ ] Bug fix
   - [x] New feature
   - [ ] Breaking change
   - [ ] Documentation update
   
   ## 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
   - [x] New regression test: `sql/partition_fullscan_reject.sql` (12 scenarios)
     - Basic rejection (no WHERE, WHERE 1=1, non-partition-key WHERE)
     - Pruning passes (WHERE on partition key)
     - GUC on/off toggle
     - enable_partition_pruning=off exemption
     - Single-partition table exemption
     - Threshold mode (threshold=2)
     - Prepared statement Param exemption
     - UPDATE/DELETE rejection
     - Subquery propagation
   - [x] Compiled with `-Werror` — zero warnings, zero errors
   - [x] Manual functional testing on utility-mode instance
   - [ ] `make installcheck` (full cluster)
   
   ## Impact
   - **Performance**: negligible — one lightweight `plan_tree_walker` after
     planning, added to the existing ~11 post-planning traversals
   - **Core files changed**: zero (only `gpcontrib/Makefile` modified)
   - **User-facing**: new ERROR for unfiltered partition queries; two new GUCs
   
   ## Compliance Checklist
   - [x] I have read the [contribution 
guide](https://cloudberry.apache.org/contribute/code)
   - [x] My code follows PostgreSQL coding conventions
   - [x] New functionality includes tests
   - [x] I have reviewed my changes for security implications
   - [x] I have requested appropriate reviewers
   
   ## Files Changed
   
   | File | Change |
   |------|--------|
   | `gpcontrib/Makefile` | Register extension in build (+4/-2) |
   | `gpcontrib/reject_partition_fullscan/reject_partition_fullscan.c` | 
Extension source (+470) |
   | `gpcontrib/reject_partition_fullscan/Makefile` | Build config (+18) |
   | `gpcontrib/reject_partition_fullscan/reject_partition_fullscan.control` | 
Extension metadata (+4) |
   | `gpcontrib/reject_partition_fullscan/reject_partition_fullscan--1.0.sql` | 
SQL install script (+8) |
   | `gpcontrib/reject_partition_fullscan/sql/partition_fullscan_reject.sql` | 
Regression test (+113) |


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to