diff --git a/docs/generated/sql/functions.md b/docs/generated/sql/functions.md
index 17664eac7b70..5cbedb9784a6 100644
--- a/docs/generated/sql/functions.md
+++ b/docs/generated/sql/functions.md
@@ -3018,7 +3018,7 @@ may increase either contention or retry errors, or both.
crdb_internal.check_consistency(stats_only: bool, start_key: bytes, end_key: bytes) → tuple{int AS range_id, bytes AS start_key, string AS start_key_pretty, string AS status, string AS detail} | Runs a consistency check on ranges touching the specified key range. an empty start or end key is treated as the minimum and maximum possible, respectively. stats_only should only be set to false when targeting a small number of ranges to avoid overloading the cluster. Each returned row contains the range ID, the status (a roachpb.CheckConsistencyResponse_Status), and verbose detail.
+crdb_internal.check_consistency(stats_only: bool, start_key: bytes, end_key: bytes) → tuple{int AS range_id, bytes AS start_key, string AS start_key_pretty, string AS status, string AS detail, interval AS duration} | Runs a consistency check on ranges touching the specified key range. an empty start or end key is treated as the minimum and maximum possible, respectively. stats_only should only be set to false when targeting a small number of ranges to avoid overloading the cluster. Each returned row contains the range ID, the status (a roachpb.CheckConsistencyResponse_Status), and verbose detail.
Example usage:
SELECT * FROM crdb_internal.check_consistency(true, ‘\x02’, ‘\x04’)
| Volatile |
diff --git a/pkg/sql/sem/builtins/fixed_oids.go b/pkg/sql/sem/builtins/fixed_oids.go
index 84c7a2bac85d..b07f58e27771 100644
--- a/pkg/sql/sem/builtins/fixed_oids.go
+++ b/pkg/sql/sem/builtins/fixed_oids.go
@@ -370,7 +370,7 @@ var builtinOidsBySignature = map[string]oid.Oid{
`crdb_internal.active_version() -> jsonb`: 1296,
`crdb_internal.approximate_timestamp(timestamp: decimal) -> timestamp`: 1298,
`crdb_internal.assignment_cast(val: anyelement, type: anyelement) -> anyelement`: 1341,
- `crdb_internal.check_consistency(stats_only: bool, start_key: bytes, end_key: bytes) -> tuple{int AS range_id, bytes AS start_key, string AS start_key_pretty, string AS status, string AS detail}`: 347,
+ `crdb_internal.check_consistency(stats_only: bool, start_key: bytes, end_key: bytes) -> tuple{int AS range_id, bytes AS start_key, string AS start_key_pretty, string AS status, string AS detail, interval AS duration}`: 347,
`crdb_internal.check_password_hash_format(password: bytes) -> string`: 1376,
`crdb_internal.cluster_id() -> uuid`: 1299,
`crdb_internal.cluster_name() -> string`: 1301,
diff --git a/pkg/sql/sem/builtins/generator_builtins.go b/pkg/sql/sem/builtins/generator_builtins.go
index 39e46869f314..6ecb00c66b3e 100644
--- a/pkg/sql/sem/builtins/generator_builtins.go
+++ b/pkg/sql/sem/builtins/generator_builtins.go
@@ -35,6 +35,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/util/errorutil"
"github.com/cockroachdb/cockroach/pkg/util/json"
"github.com/cockroachdb/cockroach/pkg/util/mon"
+ "github.com/cockroachdb/cockroach/pkg/util/timeutil"
"github.com/cockroachdb/cockroach/pkg/util/tracing"
"github.com/cockroachdb/cockroach/pkg/util/tracing/tracingpb"
"github.com/cockroachdb/errors"
@@ -1837,6 +1838,7 @@ type checkConsistencyGenerator struct {
// row and moves it to curRow. When empty, consumes from 'descs' to produce
// more rows.
remainingRows []roachpb.CheckConsistencyResponse_Result
+ curDuration time.Duration
curRow roachpb.CheckConsistencyResponse_Result
}
@@ -1889,8 +1891,8 @@ func makeCheckConsistencyGenerator(
}
var checkConsistencyGeneratorType = types.MakeLabeledTuple(
- []*types.T{types.Int, types.Bytes, types.String, types.String, types.String},
- []string{"range_id", "start_key", "start_key_pretty", "status", "detail"},
+ []*types.T{types.Int, types.Bytes, types.String, types.String, types.String, types.Interval},
+ []string{"range_id", "start_key", "start_key_pretty", "status", "detail", "duration"},
)
// ResolvedType is part of the tree.ValueGenerator interface.
@@ -1929,6 +1931,7 @@ func (c *checkConsistencyGenerator) Start(ctx context.Context, _ *kv.Txn) error
// Next is part of the tree.ValueGenerator interface.
func (c *checkConsistencyGenerator) Next(ctx context.Context) (bool, error) {
+ tBegin := timeutil.Now()
if len(c.remainingRows) == 0 {
if len(c.descs) == 0 {
return false, nil
@@ -1954,9 +1957,13 @@ func (c *checkConsistencyGenerator) Next(ctx context.Context) (bool, error) {
},
}
} else {
+ // NB: this could have more than one entry, if a range split in the
+ // meantime.
c.remainingRows = resp.Result
}
}
+
+ c.curDuration = timeutil.Since(tBegin)
c.curRow = c.remainingRows[0]
c.remainingRows = c.remainingRows[1:]
return true, nil
@@ -1964,12 +1971,18 @@ func (c *checkConsistencyGenerator) Next(ctx context.Context) (bool, error) {
// Values is part of the tree.ValueGenerator interface.
func (c *checkConsistencyGenerator) Values() (tree.Datums, error) {
+ intervalMeta := types.IntervalTypeMetadata{
+ DurationField: types.IntervalDurationField{
+ DurationType: types.IntervalDurationType_MILLISECOND,
+ },
+ }
return tree.Datums{
tree.NewDInt(tree.DInt(c.curRow.RangeID)),
tree.NewDBytes(tree.DBytes(c.curRow.StartKey)),
tree.NewDString(roachpb.Key(c.curRow.StartKey).String()),
tree.NewDString(c.curRow.Status.String()),
tree.NewDString(c.curRow.Detail),
+ tree.NewDInterval(duration.MakeDuration(c.curDuration.Nanoseconds(), 0 /* days */, 0 /* months */), intervalMeta),
}, nil
}
|