Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[memo] merge joins must use globally sorted indexes #2803

Merged
merged 3 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions sql/analyzer/indexed_joins.go
Original file line number Diff line number Diff line change
Expand Up @@ -1070,9 +1070,18 @@ func addMergeJoins(ctx *sql.Context, m *memo.Memo) error {
// Check to see if any rIndexes match that set of filters
// Remove the last matched filter
for _, lIndex := range lIndexes {
if lIndex.Order() == sql.IndexOrderNone {
// lookups can be unordered, merge indexes need to
// be globally ordered
continue
}

matchedEqFilters := matchedFiltersForLeftIndex(lIndex, join.Left.RelProps.FuncDeps().Constants(), eqFilters)
for len(matchedEqFilters) > 0 {
for _, rIndex := range rIndexes {
if rIndex.Order() == sql.IndexOrderNone {
continue
}
if rightIndexMatchesFilters(rIndex, join.Left.RelProps.FuncDeps().Constants(), matchedEqFilters) {
jb := join.Copy()
if d, ok := jb.Left.First.(*memo.Distinct); ok && lIndex.SqlIdx().IsUnique() {
Expand Down
13 changes: 9 additions & 4 deletions sql/memo/memo.go
Original file line number Diff line number Diff line change
Expand Up @@ -743,14 +743,15 @@ type SourceRel interface {

type Index struct {
// ordered list of index columns
order []sql.ColumnId
cols []sql.ColumnId
// unordered column set
set sql.ColSet
idx sql.Index
set sql.ColSet
idx sql.Index
order sql.IndexOrder
}

func (i *Index) Cols() []sql.ColumnId {
return i.order
return i.cols
}

func (i *Index) ColSet() sql.ColSet {
Expand All @@ -761,6 +762,10 @@ func (i *Index) SqlIdx() sql.Index {
return i.idx
}

func (i *Index) Order() sql.IndexOrder {
return i.order
}

type sourceBase struct {
*relBase
indexes []*Index
Expand Down
7 changes: 5 additions & 2 deletions sql/memo/rel_props.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,10 @@ func (p *relProps) populateFds() {
// strict if primary key or all nonNull and unique
columns := idxExprsColumns(idx)
strict := true
normIdx := &Index{idx: idx, order: make([]sql.ColumnId, len(columns))}
normIdx := &Index{idx: idx, cols: make([]sql.ColumnId, len(columns)), order: sql.IndexOrderNone}
if oidx, ok := idx.(sql.OrderedIndex); ok {
normIdx.order = oidx.Order()
}
for i, c := range columns {
ord := sch.IndexOfColName(strings.ToLower(c))
idOffset := firstCol + sql.ColumnId(ord)
Expand All @@ -236,7 +239,7 @@ func (p *relProps) populateFds() {
p.grp.m.HandleErr(err)
}
normIdx.set.Add(colId)
normIdx.order[i] = colId
normIdx.cols[i] = colId
if !notNull.Contains(colId) {
strict = false
}
Expand Down
8 changes: 4 additions & 4 deletions sql/memo/rel_props_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func TestPopulateFDs(t *testing.T) {
notNull: sql.NewColSet(1, 2, 3),
indexes: []*Index{
{
order: []sql.ColumnId{2, 1},
set: sql.NewColSet(1, 2),
cols: []sql.ColumnId{2, 1},
set: sql.NewColSet(1, 2),
},
},
key: sql.NewColSet(1, 2),
Expand All @@ -62,8 +62,8 @@ func TestPopulateFDs(t *testing.T) {
notNull: sql.NewColSet(1, 2, 3),
indexes: []*Index{
{
order: []sql.ColumnId{1, 2, 3},
set: sql.NewColSet(1, 2, 3),
cols: []sql.ColumnId{1, 2, 3},
set: sql.NewColSet(1, 2, 3),
},
},
key: sql.NewColSet(1, 2, 3),
Expand Down
Loading