Skip to content
Open
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
3 changes: 3 additions & 0 deletions pkg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ ALL_TESTS = [
"//pkg/sql/gcjob/gcjobnotifier:gcjobnotifier_test",
"//pkg/sql/gcjob:gcjob_test",
"//pkg/sql/gcjob_test:gcjob_test_test",
"//pkg/sql/hintpb:hintpb_test",
"//pkg/sql/hints:hints_test",
"//pkg/sql/idxrecommendations:idxrecommendations_test",
"//pkg/sql/idxusage:idxusage_test",
Expand Down Expand Up @@ -2070,6 +2071,8 @@ GO_TARGETS = [
"//pkg/sql/gcjob:gcjob",
"//pkg/sql/gcjob:gcjob_test",
"//pkg/sql/gcjob_test:gcjob_test_test",
"//pkg/sql/hintpb:hintpb",
"//pkg/sql/hintpb:hintpb_test",
"//pkg/sql/hints:hints",
"//pkg/sql/hints:hints_test",
"//pkg/sql/idxrecommendations:idxrecommendations",
Expand Down
7 changes: 7 additions & 0 deletions pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/gen/protobuf.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ PROTOBUF_SRCS = [
"//pkg/sql/catalog/schematelemetry/schematelemetrycontroller:schematelemetrycontroller_go_proto",
"//pkg/sql/contentionpb:contentionpb_go_proto",
"//pkg/sql/execinfrapb:execinfrapb_go_proto",
"//pkg/sql/hints:hints_go_proto",
"//pkg/sql/hintpb:hintpb_go_proto",
"//pkg/sql/inverted:inverted_go_proto",
"//pkg/sql/lex:lex_go_proto",
"//pkg/sql/pgwire/pgerror:pgerror_go_proto",
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ go_library(
"//pkg/sql/faketreeeval",
"//pkg/sql/flowinfra",
"//pkg/sql/gcjob/gcjobnotifier",
"//pkg/sql/hintpb",
"//pkg/sql/hints",
"//pkg/sql/idxrecommendations",
"//pkg/sql/idxusage",
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/faketreeeval/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ go_library(
"//pkg/roachpb",
"//pkg/security/username",
"//pkg/sql/catalog/descpb",
"//pkg/sql/hintpb",
"//pkg/sql/pgwire/pgcode",
"//pkg/sql/pgwire/pgerror",
"//pkg/sql/pgwire/pgnotice",
Expand Down
8 changes: 8 additions & 0 deletions pkg/sql/faketreeeval/evalctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/roachpb"
"github.com/cockroachdb/cockroach/pkg/security/username"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
"github.com/cockroachdb/cockroach/pkg/sql/hintpb"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgnotice"
Expand Down Expand Up @@ -589,6 +590,13 @@ func (ep *DummyEvalPlanner) ProcessVectorIndexFixups(
return nil
}

// InsertStatementHint is part of the eval.Planner interface.
func (ep *DummyEvalPlanner) InsertStatementHint(
ctx context.Context, statementFingerprint string, hint hintpb.StatementHintUnion,
) (int64, error) {
return 0, nil
}

// DummyPrivilegedAccessor implements the tree.PrivilegedAccessor interface by returning errors.
type DummyPrivilegedAccessor struct{}

Expand Down
39 changes: 39 additions & 0 deletions pkg/sql/hintpb/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")

proto_library(
name = "hintpb_proto",
srcs = ["statement_hint.proto"],
strip_import_prefix = "/pkg",
visibility = ["//visibility:public"],
deps = ["@com_github_gogo_protobuf//gogoproto:gogo_proto"],
)

go_proto_library(
name = "hintpb_go_proto",
compilers = ["//pkg/cmd/protoc-gen-gogoroach:protoc-gen-gogoroach_compiler"],
importpath = "github.com/cockroachdb/cockroach/pkg/sql/hintpb",
proto = ":hintpb_proto",
visibility = ["//visibility:public"],
deps = ["@com_github_gogo_protobuf//gogoproto"],
)

go_library(
name = "hintpb",
srcs = ["statement_hint.go"],
embed = [":hintpb_go_proto"],
importpath = "github.com/cockroachdb/cockroach/pkg/sql/hintpb",
visibility = ["//visibility:public"],
deps = [
"//pkg/util/protoutil",
"@com_github_cockroachdb_errors//:errors",
],
)

go_test(
name = "hintpb_test",
srcs = ["statement_hint_test.go"],
embed = [":hintpb"],
deps = ["@com_github_stretchr_testify//require"],
)
33 changes: 33 additions & 0 deletions pkg/sql/hintpb/statement_hint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2025 The Cockroach Authors.
//
// Use of this software is governed by the CockroachDB Software License
// included in the /LICENSE file.

package hintpb

import (
"github.com/cockroachdb/cockroach/pkg/util/protoutil"
"github.com/cockroachdb/errors"
)

// FromBytes converts the raw bytes from system.statement_hints into a
// StatementHintUnion object.
func FromBytes(bytes []byte) (StatementHintUnion, error) {
res := StatementHintUnion{}
if err := protoutil.Unmarshal(bytes, &res); err != nil {
return StatementHintUnion{}, err
}
if res.GetValue() == nil {
return StatementHintUnion{}, errors.New("invalid hint bytes: no value set")
}
return res, nil
}

// ToBytes converts the StatementHintUnion to a raw bytes representation that
// can be inserted into the system.statement_hints table.
func ToBytes(hint StatementHintUnion) ([]byte, error) {
if hint.GetValue() == nil {
return nil, errors.New("cannot convert empty hint to bytes")
}
return protoutil.Marshal(&hint)
}
26 changes: 26 additions & 0 deletions pkg/sql/hintpb/statement_hint.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2025 The Cockroach Authors.
//
// Use of this software is governed by the CockroachDB Software License
// included in the /LICENSE file.

syntax = "proto3";
package hintpb;

import "gogoproto/gogo.proto";

// StatementHintsUnion contains exactly one type of "external" statement hint
// that can be applied to statements with a given fingerprint using the
// system.statement_hints table.
message StatementHintUnion {
option (gogoproto.onlyone) = true;

InjectHints inject_hints = 1;
}

// InjectHints applies inline query plan hints (join and index hints) from the
// DonorSQL field to the hinted statement. The DonorSQL string must have
// the same syntactical structure as the hinted statement, with only the
// addition of inline hints.
message InjectHints {
string donor_sql = 1 [(gogoproto.customname) = "DonorSQL"];
}
42 changes: 42 additions & 0 deletions pkg/sql/hintpb/statement_hint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2025 The Cockroach Authors.
//
// Use of this software is governed by the CockroachDB Software License
// included in the /LICENSE file.

package hintpb

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestFromToBytes(t *testing.T) {
// Test writing empty hint.
_, err := ToBytes(StatementHintUnion{})
require.EqualError(t, err, "cannot convert empty hint to bytes")

// Test reading empty bytes.
_, err = FromBytes(nil)
require.EqualError(t, err, "invalid hint bytes: no value set")
_, err = FromBytes([]byte{})
require.EqualError(t, err, "invalid hint bytes: no value set")

// Test reading invalid bytes.
_, err = FromBytes([]byte{0xFF, 0xFF, 0xFF})
require.Error(t, err)

// Test that a valid hint round trips.
testRT := func(hint interface{}) {
var hintUnion StatementHintUnion
hintUnion.SetValue(hint)
bytes, err := ToBytes(hintUnion)
require.NoError(t, err)
require.NotEmpty(t, bytes)
decodedHintUnion, err := FromBytes(bytes)
require.NoError(t, err)
require.Equal(t, hint, decodedHintUnion.GetValue())
}
testRT(&InjectHints{})
testRT(&InjectHints{DonorSQL: "SELECT * FROM t"})
}
28 changes: 6 additions & 22 deletions pkg/sql/hints/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "hints",
srcs = [
"hint_cache.go",
"statement_hint.go",
"hint_table.go",
],
embed = [":hints_go_proto"],
importpath = "github.com/cockroachdb/cockroach/pkg/sql/hints",
visibility = ["//visibility:public"],
deps = [
Expand All @@ -25,6 +22,8 @@ go_library(
"//pkg/sql/catalog/descpb",
"//pkg/sql/catalog/descs",
"//pkg/sql/catalog/systemschema",
"//pkg/sql/hintpb",
"//pkg/sql/isql",
"//pkg/sql/rowenc",
"//pkg/sql/sem/tree",
"//pkg/sql/sessiondata",
Expand All @@ -34,7 +33,6 @@ go_library(
"//pkg/util/hlc",
"//pkg/util/log",
"//pkg/util/metamorphic",
"//pkg/util/protoutil",
"//pkg/util/retry",
"//pkg/util/startup",
"//pkg/util/stop",
Expand All @@ -43,28 +41,12 @@ go_library(
],
)

go_proto_library(
name = "hints_go_proto",
compilers = ["//pkg/cmd/protoc-gen-gogoroach:protoc-gen-gogoroach_compiler"],
importpath = "github.com/cockroachdb/cockroach/pkg/sql/hints",
proto = ":hints_proto",
visibility = ["//visibility:public"],
deps = ["@com_github_gogo_protobuf//gogoproto"],
)

proto_library(
name = "hints_proto",
srcs = ["statement_hint.proto"],
strip_import_prefix = "/pkg",
visibility = ["//visibility:public"],
deps = ["@com_github_gogo_protobuf//gogoproto:gogo_proto"],
)

go_test(
name = "hints_test",
size = "medium",
srcs = [
"hint_cache_test.go",
"hint_table_test.go",
"main_test.go",
],
exec_properties = select({
Expand All @@ -80,6 +62,8 @@ go_test(
"//pkg/server",
"//pkg/sql/catalog",
"//pkg/sql/catalog/descs",
"//pkg/sql/hintpb",
"//pkg/sql/isql",
"//pkg/sql/randgen",
"//pkg/sql/stats",
"//pkg/testutils",
Expand Down
Loading