Skip to content

Commit

Permalink
sql: introduce planning error hints
Browse files Browse the repository at this point in the history
This change introduces a new stage during planning, which upon
encountering a planning error adds additional user-facing hints to the
error payload.

We will be able to extend this over time to make suggestions on how to
enhance a query to avoid error.

As an example application, this change enhances errors about
now-removed columns in `crdb_internal.ranges`, `ranges_no_leases` and
the output of `SHOW RANGES`.

For example:
```
[email protected]:26257/movr> select lease_holder from [show ranges from table users];
ERROR: column "lease_holder" does not exist
SQLSTATE: 42703
HINT: To list lease holder and range size details, consider SHOW RANGES WITH DETAILS.
--
There are more SHOW RANGES options. Refer to the online documentation or execute 'SHOW RANGES ??' for details.
```

```
[email protected]:26257/movr> select database_name,table_name from crdb_internal.ranges;
ERROR: column "database_name" does not exist
SQLSTATE: 42703
DETAIL: SELECT database_name, table_name FROM crdb_internal.ranges
HINT: To list all ranges across all databases and display the database name, consider SHOW CLUSTER RANGES WITH TABLES.
--
There are more SHOW RANGES options. Refer to the online documentation or execute 'SHOW RANGES ??' for details.
```

Release note: None
  • Loading branch information
knz committed Mar 22, 2023
1 parent 1e2ea17 commit 16bdc14
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
1 change: 1 addition & 0 deletions pkg/sql/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ go_library(
"drop_tenant.go",
"drop_type.go",
"drop_view.go",
"error_hints.go",
"error_if_rows.go",
"event_log.go",
"exec_factory_util.go",
Expand Down
3 changes: 2 additions & 1 deletion pkg/sql/conn_executor_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ func (ex *connExecutor) dispatchToExecutionEngine(
err := ex.makeExecPlan(ctx, planner)
defer planner.curPlan.close(ctx)

// include gist in error reports
// Include gist in error reports.
ctx = withPlanGist(ctx, planner.instrumentation.planGist.String())
if planner.extendedEvalCtx.TxnImplicit {
planner.curPlan.flags.Set(planFlagImplicitTxn)
Expand Down Expand Up @@ -1278,6 +1278,7 @@ func (ex *connExecutor) dispatchToExecutionEngine(

// Finally, process the planning error from above.
if err != nil {
err = addPlanningErrorHints(err, &stmt)
res.SetError(err)
return nil
}
Expand Down
72 changes: 72 additions & 0 deletions pkg/sql/error_hints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2023 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package sql

import (
"strings"

"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
"github.com/cockroachdb/errors"
)

// addPlanningErrorHints is responsible for enhancing the provided
// error object with hints that inform the user about their options.
func addPlanningErrorHints(err error, stmt *Statement) error {
pgCode := pgerror.GetPGCode(err)
switch pgCode {
case pgcode.UndefinedColumn:
resolvedSQL := stmt.AST.String()

// Changes introduced in v23.1.
extraRangeDoc := false
switch {
case strings.Contains(resolvedSQL, "SHOW RANGES"):
errS := err.Error()

// The following columns are not available when using SHOW
// RANGES after the introduction of coalesced ranges.
if strings.Contains(errS, "lease_holder") || strings.Contains(errS, "range_size") {
err = errors.WithHint(err,
"To list lease holder and range size details, consider SHOW RANGES WITH DETAILS.")
extraRangeDoc = true
}

case strings.Contains(resolvedSQL, "crdb_internal.ranges" /* also matches ranges_no_leases */):
errS := err.Error()

// The following columns are not available when using SHOW
// RANGES after the introduction of coalesced ranges.
if strings.Contains(errS, "database_name") {
err = errors.WithHint(err,
"To list all ranges across all databases and display the database name, consider SHOW CLUSTER RANGES WITH TABLES.")
extraRangeDoc = true
}
if strings.Contains(errS, "schema_name") ||
strings.Contains(errS, "table_name") ||
strings.Contains(errS, "table_id") {
err = errors.WithHint(err,
"To retrieve table/schema names/IDs associated with ranges, consider SHOW [CLUSTER] RANGES WITH TABLES.")
extraRangeDoc = true
}
if strings.Contains(errS, "index_name") {
err = errors.WithHint(err,
"To retrieve index names associated with ranges, consider SHOW [CLUSTER] RANGES WITH INDEXES.")
extraRangeDoc = true
}
}
if extraRangeDoc {
err = errors.WithHint(err,
"There are more SHOW RANGES options. Refer to the online documentation or execute 'SHOW RANGES ??' for details.")
}
}
return err
}
38 changes: 38 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/show_ranges
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,41 @@ CREATE TABLE v0 (c1 BIT PRIMARY KEY );

statement error pgcode 42846 pq: crdb_internal.encode_key\(\): invalid cast: bytes -> bit
SHOW RANGE FROM TABLE v0 FOR ROW ( b'\x68')

subtest prev_interface_error_hints

statement error pgcode 42703 .*\nHINT.*lease holder and range size
SELECT lease_holder FROM [SHOW RANGES FROM TABLE v0]

statement error pgcode 42703 .*\nHINT.*lease holder and range size
SELECT lease_holder FROM [show ranges from table v0]

statement error pgcode 42703 .*\nHINT.*lease holder and range size
SELECT lease_holder_locality FROM [SHOW RANGES FROM TABLE v0]

statement error pgcode 42703 .*\nHINT.*lease holder and range size
SELECT range_size FROM [SHOW RANGES FROM TABLE v0]

statement error pgcode 42703 .*\nHINT.*lease holder and range size
SELECT range_size_mb FROM [SHOW RANGES FROM TABLE v0]

statement error pgcode 42703 .*\nHINT.*display the database name
SELECT database_name FROM crdb_internal.ranges

statement error pgcode 42703 .*\nHINT.*display the database name
SELECT database_name FROM CRDB_INTERNAL."ranges"

statement error pgcode 42703 .*\nHINT.*display the database name
SELECT database_name FROM crdb_internal.ranges_no_leases

statement error pgcode 42703 .*\nHINT.*To retrieve table/schema.*with ranges
SELECT table_name FROM crdb_internal.ranges

statement error pgcode 42703 .*\nHINT.*To retrieve table/schema.*with ranges
SELECT table_id FROM crdb_internal.ranges

statement error pgcode 42703 .*\nHINT.*To retrieve table/schema.*with ranges
SELECT schema_name FROM crdb_internal.ranges

statement error pgcode 42703 .*\nHINT.*To retrieve index.*with ranges
SELECT index_name FROM crdb_internal.ranges

0 comments on commit 16bdc14

Please sign in to comment.