Skip to content

Commit 435e9d4

Browse files
committed
tree: also remove existing hints from target during hint injection
During hint injection, also remove existing hints from the target statement if they are not present in the donor statement. This makes it easier to understand the rewrite performed by hint injection, as well as makes it possible for hint injection to remove hints. Informs: #153633 Release note: None
1 parent f868574 commit 435e9d4

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

pkg/sql/sem/tree/inject_hints.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,13 @@ func (v *hintInjectionVisitor) VisitTablePre(expr TableExpr) (recurse bool, newE
211211
donorExpr := v.hd.walk[v.walkIdx]
212212
v.walkIdx += 1
213213

214-
// Copy hints from the corresponding donor TableExpr.
214+
// Remove any existing hints from the original TableExpr, and copy hints from
215+
// the corresponding donor TableExpr.
215216
switch donor := donorExpr.(type) {
216217
case *AliasedTableExpr:
217218
switch orig := expr.(type) {
218219
case *AliasedTableExpr:
219-
if donor.IndexFlags != nil {
220+
if !donor.IndexFlags.Equal(orig.IndexFlags) {
220221
// Create a new node with any pre-existing inline hints replaced with
221222
// hints from the donor.
222223
newNode := *orig

pkg/sql/sem/tree/inject_hints_test.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func TestInjectHints(t *testing.T) {
8282
originalSQL: "SELECT * FROM t@idx",
8383
donorSQL: "SELECT * FROM t@idx",
8484
expectedSQL: "SELECT * FROM t@idx",
85-
expectChanged: true, // we still perform a rewrite, and still return true
85+
expectChanged: false,
8686
},
8787
{
8888
name: "different constants should work",
@@ -153,11 +153,11 @@ func TestInjectHints(t *testing.T) {
153153
expectChanged: true,
154154
},
155155
{
156-
name: "hint unchanged by donor",
156+
name: "hint overwritten by donor",
157157
originalSQL: "SELECT * FROM t@idx",
158-
donorSQL: "SELECT * FROM t",
159-
expectedSQL: "SELECT * FROM t@idx",
160-
expectChanged: false,
158+
donorSQL: "SELECT * FROM t@{NO_FULL_SCAN}",
159+
expectedSQL: "SELECT * FROM t@{NO_FULL_SCAN}",
160+
expectChanged: true,
161161
},
162162
{
163163
name: "subquery in join condition",
@@ -287,6 +287,13 @@ func TestInjectHints(t *testing.T) {
287287
expectedSQL: "SELECT * FROM a INNER JOIN b ON true",
288288
expectChanged: true,
289289
},
290+
{
291+
name: "remove hints",
292+
originalSQL: "SELECT * FROM a@{NO_FULL_SCAN,IGNORE_FOREIGN_KEYS} INNER LOOKUP JOIN b@b_c_idx ON true",
293+
donorSQL: "SELECT * FROM a JOIN b ON true",
294+
expectedSQL: "SELECT * FROM a JOIN b ON true",
295+
expectChanged: true,
296+
},
290297
}
291298

292299
st := cluster.MakeTestingClusterSettings()

pkg/sql/sem/tree/select.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package tree
1616

1717
import (
1818
"fmt"
19+
"slices"
1920

2021
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
2122
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
@@ -480,6 +481,28 @@ func (ih *IndexFlags) Check() error {
480481
return nil
481482
}
482483

484+
// Equal returns true if these IndexFlags equal the other IndexFlags.
485+
func (ih *IndexFlags) Equal(other *IndexFlags) bool {
486+
if ih == nil || other == nil {
487+
return ih == other
488+
}
489+
return ih.Index == other.Index &&
490+
ih.IndexID == other.IndexID &&
491+
ih.Direction == other.Direction &&
492+
ih.NoIndexJoin == other.NoIndexJoin &&
493+
ih.NoZigzagJoin == other.NoZigzagJoin &&
494+
ih.NoFullScan == other.NoFullScan &&
495+
ih.AvoidFullScan == other.AvoidFullScan &&
496+
ih.IgnoreForeignKeys == other.IgnoreForeignKeys &&
497+
ih.IgnoreUniqueWithoutIndexKeys == other.IgnoreUniqueWithoutIndexKeys &&
498+
ih.ForceInvertedIndex == other.ForceInvertedIndex &&
499+
ih.ForceZigzag == other.ForceZigzag &&
500+
slices.Equal(ih.ZigzagIndexes, other.ZigzagIndexes) &&
501+
slices.Equal(ih.ZigzagIndexIDs, other.ZigzagIndexIDs) &&
502+
((ih.FamilyID == nil && other.FamilyID == nil) ||
503+
(ih.FamilyID != nil && other.FamilyID != nil && *ih.FamilyID == *other.FamilyID))
504+
}
505+
483506
var enableFamilyIDIndexHintForTests = false
484507

485508
// TestingEnableFamilyIndexHint enables the use of Family index hint

0 commit comments

Comments
 (0)