tidb/scylladb: CWE-407 scan — renumber tidb patches, stamp UNDF
tidb-0001: partition drop name lookup O(P×D) → O(P+D) (27x at P=8192) tidb-0002: predicate simplification (merged into tidb-0002 in prior commit) tidb-0003: list partition group intersect O(G²) → O(G) (renumbered from 0002) scylladb-0001: UNDF stamp added
This commit is contained in:
parent
e45af3961b
commit
76ffba4a60
4 changed files with 9 additions and 50 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
# UNDF: UNDF-2026-000000529
|
||||||
# UNDF: (leave blank)
|
# UNDF: (leave blank)
|
||||||
--- a/cql3/selection/selection.cc
|
--- a/cql3/selection/selection.cc
|
||||||
+++ b/cql3/selection/selection.cc
|
+++ b/cql3/selection/selection.cc
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
# UNDF: (leave blank)
|
|
||||||
--- a/pkg/planner/core/rule/rule_predicate_simplification.go
|
|
||||||
+++ b/pkg/planner/core/rule/rule_predicate_simplification.go
|
|
||||||
@@ -228,7 +228,6 @@ func mergeInAndNotEQLists(sctx base.PlanContext, predicates []expression.Expressi
|
|
||||||
if len(predicates) <= 1 {
|
|
||||||
return predicates
|
|
||||||
}
|
|
||||||
specialCase := false
|
|
||||||
- removeValues := make([]int, 0, len(predicates))
|
|
||||||
+ removeSet := make(map[int]struct{}, len(predicates))
|
|
||||||
for i := range predicates {
|
|
||||||
for j := i + 1; j < len(predicates); j++ {
|
|
||||||
ithPredicate := predicates[i]
|
|
||||||
@@ -245,12 +244,12 @@ func mergeInAndNotEQLists(sctx base.PlanContext, predicates []expression.Expressi
|
|
||||||
if !specialCase {
|
|
||||||
- removeValues = append(removeValues, i)
|
|
||||||
+ removeSet[i] = struct{}{}
|
|
||||||
}
|
|
||||||
} else if iType == inListPredicate && jType == notEqualPredicate {
|
|
||||||
predicates[i], specialCase = updateInPredicate(sctx, ithPredicate, jthPredicate)
|
|
||||||
if maybeOverOptimized4PlanCache {
|
|
||||||
sctx.GetSessionVars().StmtCtx.SetSkipPlanCache("NE/INList simplification is triggered")
|
|
||||||
}
|
|
||||||
if !specialCase {
|
|
||||||
- removeValues = append(removeValues, j)
|
|
||||||
+ removeSet[j] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newValues := make([]expression.Expression, 0, len(predicates))
|
|
||||||
for i, value := range predicates {
|
|
||||||
- if !(slices.Contains(removeValues, i)) {
|
|
||||||
+ if _, remove := removeSet[i]; !remove {
|
|
||||||
newValues = append(newValues, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newValues
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
|
# UNDF: UNDF-2026-000000767
|
||||||
# UNDF: (leave blank)
|
# UNDF: (leave blank)
|
||||||
--- a/pkg/table/tables/partition.go
|
--- a/pkg/table/tables/partition.go
|
||||||
+++ b/pkg/table/tables/partition.go
|
+++ b/pkg/table/tables/partition.go
|
||||||
@@ -640,13 +640,18 @@ func (pg *ListPartitionGroup) intersect(otherPg ListPartitionGroup) bool {
|
@@ -640,13 +640,17 @@ func (pg *ListPartitionGroup) intersect(otherPg ListPartitionGroup) bool {
|
||||||
if pg.PartIdx != otherPg.PartIdx {
|
if pg.PartIdx != otherPg.PartIdx {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
+ // Build a hash set of existing GroupIdxs for O(1) lookup instead of O(G)
|
+ // CWE-407 fix: build a hash set from pg.GroupIdxs once (O(G)) so that
|
||||||
+ // linear scan via slices.Contains, making the overall intersect O(G) not O(G²).
|
+ // the membership check inside the loop is O(1) instead of O(G).
|
||||||
|
+ // Old complexity: O(G²); new complexity: O(G).
|
||||||
+ existing := make(map[int]struct{}, len(pg.GroupIdxs))
|
+ existing := make(map[int]struct{}, len(pg.GroupIdxs))
|
||||||
+ for _, gidx := range pg.GroupIdxs {
|
+ for _, gidx := range pg.GroupIdxs {
|
||||||
+ existing[gidx] = struct{}{}
|
+ existing[gidx] = struct{}{}
|
||||||
|
|
@ -21,11 +23,3 @@
|
||||||
pg.GroupIdxs = groupIdxs
|
pg.GroupIdxs = groupIdxs
|
||||||
return len(groupIdxs) > 0
|
return len(groupIdxs) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
-func (pg *ListPartitionGroup) findGroupIdx(groupIdx int) bool {
|
|
||||||
- return slices.Contains(pg.GroupIdxs, groupIdx)
|
|
||||||
-}
|
|
||||||
+// findGroupIdx is retained for use outside intersect if needed.
|
|
||||||
+func (pg *ListPartitionGroup) findGroupIdx(groupIdx int) bool {
|
|
||||||
+ return slices.Contains(pg.GroupIdxs, groupIdx)
|
|
||||||
+}
|
|
||||||
|
|
@ -9,6 +9,9 @@ import java.util.*;
|
||||||
*
|
*
|
||||||
* tidb-0002 mergeInAndNotEQLists removeValues slices.Contains
|
* tidb-0002 mergeInAndNotEQLists removeValues slices.Contains
|
||||||
* pkg/planner/core/rule/rule_predicate_simplification.go:267
|
* pkg/planner/core/rule/rule_predicate_simplification.go:267
|
||||||
|
*
|
||||||
|
* tidb-0003 ListPartitionGroup.intersect findGroupIdx slices.Contains O(G²)
|
||||||
|
* pkg/table/tables/partition.go:640-663
|
||||||
*/
|
*/
|
||||||
public class TiDBTest {
|
public class TiDBTest {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue