MDEV-17613 Read sole now-partition for non-historical versioned query#5386
MDEV-17613 Read sole now-partition for non-historical versioned query#5386midenok wants to merge 5 commits into
Conversation
midenok
commented
Jul 14, 2026
There was a problem hiding this comment.
Code Review
This pull request refactors partition pruning to use a local parts_bitmap within PART_PRUNE_PARAM instead of directly modifying part_info->read_partitions during the pruning process. At the end of pruning, the candidate partitions are narrowed by intersecting read_partitions with the newly computed parts_bitmap. A critical correctness issue was identified in sql/opt_range.cc where the return value retval is evaluated against the pre-pruned read_partitions bitmap rather than the post-intersection bitmap, which can lead to incorrect results. A code suggestion has been provided to update retval after the intersection.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
There was a problem hiding this comment.
Pull request overview
Optimizes implicit (non-historical) queries on system-versioned tables whose history is stored in partitions by restricting reads to the current (“now”) partition, rather than relying on a row_end predicate, and adjusts partition pruning to respect an already-restricted candidate partition set.
Changes:
- Restrict
read_partitionsto the current versioning partition for implicit (noFOR SYSTEM_TIME) queries, and adjust guarding for repeated executions. - Refactor partition pruning to accumulate results in a separate bitmap and intersect with the incoming candidate
read_partitions(never widening it). - Add
partition_element::bitmap_range()helper and update related range computations; update versioning test expectation for EXPLAIN output.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| sql/sql_select.cc | Restricts read_partitions to the “now” partition for implicit versioned queries. |
| sql/opt_range.cc | Makes pruning intersect-only by using a separate bitmap and intersecting with candidate partitions. |
| sql/partition_info.cc | Updates debug assertion to use bitmap_range() / total partitions helper. |
| sql/partition_element.h | Adds bitmap_range() helper to compute leaf-bitmap ranges for partitions/subpartitions. |
| sql/ha_partition.h | Uses bitmap_range() when summing records across a partition and its subpartitions. |
| mysql-test/suite/versioning/r/partition.result | Updates expected EXPLAIN Extra output (no longer “Using where” for implicit query). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3160687 to
2ad4331
Compare
2ad4331 to
8f335ac
Compare
8f335ac to
1414055
Compare
Returns bit range for partition element.
prune_partitions() built the used-partition set directly in read_partitions: it cleared it, let find_used_partitions*() fill it, and in the index-merge case used it as scratch too - both buffer and result. The patch adds PART_PRUNE_PARAM::parts_bitmap and builds the return into it instead. read_partitions is produced from it only at the end: copied when the condition was analyzed (IMPOSSIBLE included, parts_bitmap left empty), or set to all locked partitions via mark_all_partitions_as_used() when nothing could be pruned. Pure refactoring: read_partitions ends up identical on every path. It decouples the pruning scratch from read_partitions, so a later commit can switch the final bitmap_copy() to bitmap_intersect() - letting pruning narrow a pre-set read_partitions (e.g. a versioned table selecting only its current partition) instead of overwriting it.
…ead of full rewrite read_partitions is reset from lock_partitions once per statement in open_table() (set_partition_bitmaps()), and prune_partitions() only intersects it with the pruned set instead of rebuilding it. mark_all_partitions_as_used() is dropped. Pure refactoring, results unchanged. It lets a restriction set on read_partitions before pruning survive it - needed when read_partitions is pre-restricted, e.g. a versioned table whose history is partitioned reads only the current partition.
When a versioned table stores its history in partitions, an implicit query (no FOR SYSTEM_TIME) needs only current rows, which all live in the current partition. Restrict read_partitions to that partition in vers_setup_conds() instead of relying on a row_end condition. read_partitions is reset to all partitions every statement in open_table(), so this restriction must be re-applied on each execution. Guard it with !vers_conditions.was_set() rather than !is_set(): set_all() sets type (flips is_set()) but not orig_type (was_set()), so is_set() would stay true across prepared-statement / stored-procedure re-executions and skip the restriction, leaving history partitions readable - rows matched then grow on each execute/call. EXPLAIN no longer shows "Using where" for such a query: correctness now comes from partition selection rather than a row_end filter.
Avoid result fluctuations with different storage engines.
1414055 to
99fd626
Compare