Skip to content

Commit

Permalink
*: Update the UniqueID of partition expression columns in LIST partit…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-chi-bot authored and qw4990 committed Mar 27, 2023
1 parent 38e7d89 commit 7f9b4fd
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 22 deletions.
2 changes: 1 addition & 1 deletion planner/core/partition_prune.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func PartitionPruning(ctx sessionctx.Context, tbl table.PartitionedTable, conds
ret := s.convertToIntSlice(rangeOr, pi, partitionNames)
return ret, nil
case model.PartitionTypeList:
return s.pruneListPartition(ctx, tbl, partitionNames, conds)
return s.pruneListPartition(ctx, tbl, partitionNames, conds, columns)
}
return []int{FullRange}, nil
}
37 changes: 37 additions & 0 deletions planner/core/partition_pruner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,43 @@ func TestRangePartitionPredicatePruner(t *testing.T) {
}
}

func TestIssue42135(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec(`create database issue42135`)
tk.MustExec(`use issue42135`)
tk.MustExec("CREATE TABLE `tx1` (`ID` varchar(13), `a` varchar(13), `b` varchar(4000), `ltype` int(5) NOT NULL)")
tk.MustExec("CREATE TABLE `tx2` (`ID` varchar(13), `rid` varchar(12), `a` varchar(9), `b` varchar(8), `c` longtext, `d` varchar(12), `ltype` int(5) NOT NULL) PARTITION BY LIST (`ltype`) (PARTITION `p1` VALUES IN (501), PARTITION `p2` VALUES IN (502))")
tk.MustExec("insert into tx1 values(1,1,1,501)")
tk.MustExec("insert into tx2 values(1,1,1,1,1,1,501)")
tk.MustExec(`analyze table tx1`)
tk.MustExec(`analyze table tx2`)
tk.MustQuery(`select * from tx1 inner join tx2 on tx1.ID=tx2.ID and tx1.ltype=tx2.ltype where tx2.rid='1'`).Check(testkit.Rows("1 1 1 501 1 1 1 1 1 1 501"))
tk.MustQuery(`explain format='brief' select * from tx1 inner join tx2 on tx1.ID=tx2.ID and tx1.ltype=tx2.ltype where tx2.rid='1'`).Check(testkit.Rows(""+
"HashJoin 1.00 root inner join, equal:[eq(issue42135.tx1.id, issue42135.tx2.id) eq(issue42135.tx1.ltype, issue42135.tx2.ltype)]",
`├─TableReader(Build) 1.00 root partition:all data:Selection`,
`│ └─Selection 1.00 cop[tikv] eq(issue42135.tx2.rid, "1"), not(isnull(issue42135.tx2.id))`,
`│ └─TableFullScan 1.00 cop[tikv] table:tx2 keep order:false`,
`└─TableReader(Probe) 1.00 root data:Selection`,
` └─Selection 1.00 cop[tikv] not(isnull(issue42135.tx1.id))`,
` └─TableFullScan 1.00 cop[tikv] table:tx1 keep order:false`))

tk.MustExec(`drop table tx2`)
tk.MustExec("CREATE TABLE `tx2` (`ID` varchar(13), `rid` varchar(12), `a` varchar(9), `b` varchar(8), `c` longtext, `d` varchar(12), `ltype` int(5) NOT NULL) PARTITION BY LIST COLUMNS (`ltype`,d) (PARTITION `p1` VALUES IN ((501,1)), PARTITION `p2` VALUES IN ((502,1)))")
tk.MustExec("insert into tx2 values(1,1,1,1,1,1,501)")
tk.MustExec(`analyze table tx2`)
tk.MustQuery(`select * from tx1 inner join tx2 on tx1.ID=tx2.ID and tx1.ltype=tx2.ltype where tx2.rid='1'`).Check(testkit.Rows("1 1 1 501 1 1 1 1 1 1 501"))
tk.MustQuery(`explain format='brief' select * from tx1 inner join tx2 on tx1.ID=tx2.ID and tx1.ltype=tx2.ltype where tx2.rid='1'`).Check(testkit.Rows(""+
"HashJoin 1.00 root inner join, equal:[eq(issue42135.tx1.id, issue42135.tx2.id) eq(issue42135.tx1.ltype, issue42135.tx2.ltype)]",
"├─TableReader(Build) 1.00 root partition:all data:Selection",
"│ └─Selection 1.00 cop[tikv] eq(issue42135.tx2.rid, \"1\"), not(isnull(issue42135.tx2.id))",
"│ └─TableFullScan 1.00 cop[tikv] table:tx2 keep order:false",
"└─TableReader(Probe) 1.00 root data:Selection",
" └─Selection 1.00 cop[tikv] not(isnull(issue42135.tx1.id))",
" └─TableFullScan 1.00 cop[tikv] table:tx1 keep order:false"))
}

func TestHashPartitionPruning(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
Expand Down
47 changes: 26 additions & 21 deletions planner/core/rule_partition_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,21 +359,30 @@ func (s *partitionProcessor) processHashPartition(ds *DataSource, pi *model.Part
// listPartitionPruner uses to prune partition for list partition.
type listPartitionPruner struct {
*partitionProcessor
ctx sessionctx.Context
pi *model.PartitionInfo
partitionNames []model.CIStr
colIDToUniqueID map[int64]int64
fullRange map[int]struct{}
listPrune *tables.ForListPruning
ctx sessionctx.Context
pi *model.PartitionInfo
partitionNames []model.CIStr
fullRange map[int]struct{}
listPrune *tables.ForListPruning
}

func newListPartitionPruner(ctx sessionctx.Context, tbl table.Table, partitionNames []model.CIStr,
s *partitionProcessor, conds []expression.Expression, pruneList *tables.ForListPruning) *listPartitionPruner {
colIDToUniqueID := make(map[int64]int64)
for _, cond := range conds {
condCols := expression.ExtractColumns(cond)
for _, c := range condCols {
colIDToUniqueID[c.ID] = c.UniqueID
s *partitionProcessor, conds []expression.Expression, pruneList *tables.ForListPruning, columns []*expression.Column) *listPartitionPruner {
pruneList = pruneList.Clone()
for i := range pruneList.PruneExprCols {
for j := range columns {
if columns[j].ID == pruneList.PruneExprCols[i].ID {
pruneList.PruneExprCols[i].UniqueID = columns[j].UniqueID
break
}
}
}
for i := range pruneList.ColPrunes {
for j := range columns {
if columns[j].ID == pruneList.ColPrunes[i].ExprCol.ID {
pruneList.ColPrunes[i].ExprCol.UniqueID = columns[j].UniqueID
break
}
}
}
fullRange := make(map[int]struct{})
Expand All @@ -383,7 +392,6 @@ func newListPartitionPruner(ctx sessionctx.Context, tbl table.Table, partitionNa
ctx: ctx,
pi: tbl.Meta().Partition,
partitionNames: partitionNames,
colIDToUniqueID: colIDToUniqueID,
fullRange: fullRange,
listPrune: pruneList,
}
Expand Down Expand Up @@ -526,9 +534,6 @@ func (l *listPartitionPruner) detachCondAndBuildRange(conds []expression.Express
colLen := make([]int, 0, len(exprCols))
for _, c := range exprCols {
c = c.Clone().(*expression.Column)
if uniqueID, ok := l.colIDToUniqueID[c.ID]; ok {
c.UniqueID = uniqueID
}
cols = append(cols, c)
colLen = append(colLen, types.UnspecifiedLength)
}
Expand Down Expand Up @@ -594,14 +599,14 @@ func (l *listPartitionPruner) findUsedListPartitions(conds []expression.Expressi
}

func (s *partitionProcessor) findUsedListPartitions(ctx sessionctx.Context, tbl table.Table, partitionNames []model.CIStr,
conds []expression.Expression) ([]int, error) {
conds []expression.Expression, columns []*expression.Column) ([]int, error) {
pi := tbl.Meta().Partition
partExpr, err := tbl.(partitionTable).PartitionExpr()
if err != nil {
return nil, err
}

listPruner := newListPartitionPruner(ctx, tbl, partitionNames, s, conds, partExpr.ForListPruning)
listPruner := newListPartitionPruner(ctx, tbl, partitionNames, s, conds, partExpr.ForListPruning, columns)
var used map[int]struct{}
if partExpr.ForListPruning.ColPrunes == nil {
used, err = listPruner.findUsedListPartitions(conds)
Expand All @@ -624,8 +629,8 @@ func (s *partitionProcessor) findUsedListPartitions(ctx sessionctx.Context, tbl
}

func (s *partitionProcessor) pruneListPartition(ctx sessionctx.Context, tbl table.Table, partitionNames []model.CIStr,
conds []expression.Expression) ([]int, error) {
used, err := s.findUsedListPartitions(ctx, tbl, partitionNames, conds)
conds []expression.Expression, columns []*expression.Column) ([]int, error) {
used, err := s.findUsedListPartitions(ctx, tbl, partitionNames, conds, columns)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -872,7 +877,7 @@ func (s *partitionProcessor) processRangePartition(ds *DataSource, pi *model.Par
}

func (s *partitionProcessor) processListPartition(ds *DataSource, pi *model.PartitionInfo, opt *logicalOptimizeOp) (LogicalPlan, error) {
used, err := s.pruneListPartition(ds.SCtx(), ds.table, ds.partitionNames, ds.allConds)
used, err := s.pruneListPartition(ds.SCtx(), ds.table, ds.partitionNames, ds.allConds, ds.TblCols)
if err != nil {
return nil, err
}
Expand Down
23 changes: 23 additions & 0 deletions table/tables/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,29 @@ func generateListPartitionExpr(ctx sessionctx.Context, tblInfo *model.TableInfo,
return ret, nil
}

// Clone a copy of ForListPruning
func (lp *ForListPruning) Clone() *ForListPruning {
ret := *lp
if ret.LocateExpr != nil {
ret.LocateExpr = lp.LocateExpr.Clone()
}
if ret.PruneExpr != nil {
ret.PruneExpr = lp.PruneExpr.Clone()
}
ret.PruneExprCols = make([]*expression.Column, 0, len(lp.PruneExprCols))
for i := range lp.PruneExprCols {
c := lp.PruneExprCols[i].Clone().(*expression.Column)
ret.PruneExprCols = append(ret.PruneExprCols, c)
}
ret.ColPrunes = make([]*ForListColumnPruning, 0, len(lp.ColPrunes))
for i := range lp.ColPrunes {
l := *lp.ColPrunes[i]
l.ExprCol = l.ExprCol.Clone().(*expression.Column)
ret.ColPrunes = append(ret.ColPrunes, &l)
}
return &ret
}

func (lp *ForListPruning) buildListPruner(ctx sessionctx.Context, tblInfo *model.TableInfo, exprCols []*expression.Column,
columns []*expression.Column, names types.NameSlice) error {
pi := tblInfo.GetPartitionInfo()
Expand Down

0 comments on commit 7f9b4fd

Please sign in to comment.