Skip to content

Commit

Permalink
planner: reverse the OFFSET when outer join's inner side is unique
Browse files Browse the repository at this point in the history
  • Loading branch information
winoros committed Oct 8, 2024
1 parent f31b091 commit e0187f8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
38 changes: 32 additions & 6 deletions pkg/expression/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,47 @@ func (s *Schema) RetrieveColumn(col *Column) *Column {
}

// IsUniqueKey checks if this column is a unique key.
func (s *Schema) IsUniqueKey(col *Column) bool {
func (s *Schema) IsUniqueKey(cols ...*Column) bool {
for _, key := range s.Keys {
if len(key) == 1 && key[0].EqualColumn(col) {
return true
if len(key) > len(cols) {
continue
}
allFound := true
for _, keyCols := range key {
for _, col := range cols {
if !keyCols.EqualColumn(col) {
allFound = false
break
}
}
}
if !allFound {
continue
}
return true
}
return false
}

// IsUnique checks if this column is a unique key which may contain duplicate nulls .
func (s *Schema) IsUnique(col *Column) bool {
func (s *Schema) IsUnique(cols ...*Column) bool {
for _, key := range s.UniqueKeys {
if len(key) == 1 && key[0].EqualColumn(col) {
return true
if len(key) > len(cols) {
continue
}
allFound := true
for _, keyCols := range key {
for _, col := range cols {
if !keyCols.EqualColumn(col) {
allFound = false
break
}
}
}
if !allFound {
continue
}
return true
}
return false
}
Expand Down
23 changes: 22 additions & 1 deletion pkg/planner/core/operator/logicalop/logical_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -1076,9 +1076,30 @@ func (p *LogicalJoin) pushDownTopNToChild(topN *LogicalTopN, idx int, opt *optim
}
}
}
count, offset := topN.Count+topN.Offset, uint64(0)
if p.JoinType == LeftOuterJoin {
innerChild := p.Children()[1]
innerJoinKey := make([]*expression.Column, 0, len(p.EqualConditions))
for _, eqCond := range p.EqualConditions {
innerJoinKey = append(innerJoinKey, eqCond.GetArgs()[1].(*expression.Column))
}
if innerChild.Schema().IsUniqueKey(innerJoinKey...) || innerChild.Schema().IsUnique(innerJoinKey...) {
count, offset = topN.Count, topN.Offset
}
} else if p.JoinType == RightOuterJoin {
innerChild := p.Children()[0]
innerJoinKey := make([]*expression.Column, 0, len(p.EqualConditions))
for _, eqCond := range p.EqualConditions {
innerJoinKey = append(innerJoinKey, eqCond.GetArgs()[0].(*expression.Column))
}
if innerChild.Schema().IsUniqueKey(innerJoinKey...) || innerChild.Schema().IsUnique(innerJoinKey...) {
count, offset = topN.Count, topN.Offset
}
}

newTopN := LogicalTopN{
Count: topN.Count + topN.Offset,
Count: count,
Offset: offset,
ByItems: make([]*util.ByItems, len(topN.ByItems)),
PreferLimitToCop: topN.PreferLimitToCop,
}.Init(topN.SCtx(), topN.QueryBlockOffset())
Expand Down

0 comments on commit e0187f8

Please sign in to comment.