Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
39324: jobs: add SHOW JOB command r=spaskob a=spaskob



Co-authored-by: Spas Bojanov <[email protected]>
Co-authored-by: Spas Bojanov <[email protected]>
  • Loading branch information
3 people committed Aug 8, 2019
2 parents 3c69b46 + 42269dc commit a78892f
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 40 deletions.
1 change: 1 addition & 0 deletions docs/generated/sql/bnf/show_jobs.bnf
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
show_jobs_stmt ::=
'SHOW' 'AUTOMATIC' 'JOBS'
| 'SHOW' 'JOBS'
| 'SHOW' 'JOB' iconst64
9 changes: 4 additions & 5 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,10 @@ show_partitions_stmt ::=
| 'SHOW' 'PARTITIONS' 'FROM' 'INDEX' table_index_name

show_jobs_stmt ::=
'SHOW' opt_automatic 'JOBS'
'SHOW' 'AUTOMATIC' 'JOBS'
| 'SHOW' 'JOBS'
| 'SHOW' 'JOBS' select_stmt
| 'SHOW' 'JOB' a_expr

show_queries_stmt ::=
'SHOW' opt_cluster 'QUERIES'
Expand Down Expand Up @@ -1166,10 +1169,6 @@ table_index_name ::=
table_name '@' index_name
| standalone_index_name

opt_automatic ::=
'AUTOMATIC'
|

opt_cluster ::=
'CLUSTER'
| 'LOCAL'
Expand Down
5 changes: 0 additions & 5 deletions pkg/cmd/docgen/diagrams.go
Original file line number Diff line number Diff line change
Expand Up @@ -1127,11 +1127,6 @@ var specs = []stmtSpec{
replace: map[string]string{"var_name": "table_name"},
unlink: []string{"table_name"},
},
{
name: "show_jobs",
stmt: "show_jobs_stmt",
inline: []string{"opt_automatic"},
},
{
name: "show_keys",
stmt: "show_stmt",
Expand Down
46 changes: 27 additions & 19 deletions pkg/sql/delegate/show_jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,34 @@ import (
)

func (d *delegator) delegateShowJobs(n *tree.ShowJobs) (tree.Statement, error) {
var typePredicate string
if n.Automatic {
typePredicate = fmt.Sprintf("job_type = '%s'", jobspb.TypeAutoCreateStats)
const (
selectClause = `SELECT job_id, job_type, description, statement, user_name, status,
running_status, created, started, finished, modified,
fraction_completed, error, coordinator_id
FROM crdb_internal.jobs`
)
var typePredicate, whereClause, orderbyClause string
if n.Jobs == nil {
// Display all [only automatic] jobs without selecting specific jobs.
if n.Automatic {
typePredicate = fmt.Sprintf("job_type = '%s'", jobspb.TypeAutoCreateStats)
} else {
typePredicate = fmt.Sprintf(
"(job_type IS NULL OR job_type != '%s')", jobspb.TypeAutoCreateStats,
)
}
// The query intends to present:
// - first all the running jobs sorted in order of start time,
// - then all completed jobs sorted in order of completion time.
whereClause = fmt.Sprintf(
`WHERE %s AND (finished IS NULL OR finished > now() - '12h':::interval)`, typePredicate)
// The "ORDER BY" clause below exploits the fact that all
// running jobs have finished = NULL.
orderbyClause = `ORDER BY COALESCE(finished, now()) DESC, started DESC`
} else {
typePredicate = fmt.Sprintf(
"(job_type != '%s' OR job_type IS NULL)", jobspb.TypeAutoCreateStats,
)
// Limit the jobs displayed to the select statement in n.Jobs.
whereClause = fmt.Sprintf(`WHERE job_id in (%s)`, n.Jobs.String())
}

// The query intends to present:
// - first all the running jobs sorted in order of start time,
// - then all completed jobs sorted in order of completion time.
// The "ORDER BY" clause below exploits the fact that all
// running jobs have finished = NULL.
return parse(fmt.Sprintf(
`SELECT job_id, job_type, description, statement, user_name, status, running_status, created,
started, finished, modified, fraction_completed, error, coordinator_id
FROM crdb_internal.jobs
WHERE %s
AND (finished IS NULL OR finished > now() - '12h':::interval)
ORDER BY COALESCE(finished, now()) DESC, started DESC`, typePredicate,
))
return parse(fmt.Sprintf("%s %s %s", selectClause, whereClause, orderbyClause))
}
1 change: 1 addition & 0 deletions pkg/sql/explain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func TestStatementReuses(t *testing.T) {
`SHOW CONSTRAINTS FROM a`,
`SHOW DATABASES`,
`SHOW INDEXES FROM a`,
`SHOW JOB 1`,
`SHOW JOBS`,
`SHOW ROLES`,
`SHOW SCHEMAS`,
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/logictest/testdata/planner_test/explain
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ sort · ·
│ order -"coalesce",-started
└── render · ·
└── filter · ·
│ filter ((job_type != 'AUTO CREATE STATS') OR (job_type IS NULL)) AND ((finished IS NULL) OR (finished > (now() - '12:00:00')))
│ filter ((job_type IS NULL) OR (job_type != 'AUTO CREATE STATS')) AND ((finished IS NULL) OR (finished > (now() - '12:00:00')))
└── values · ·
· size 16 columns, 0 rows

Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/opt/exec/execbuilder/testdata/explain
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ render · ·
│ order -column17,-started
└── render · ·
└── filter · ·
│ filter ((job_type != 'AUTO CREATE STATS') OR (job_type IS NULL)) AND ((finished IS NULL) OR (finished > (now() - '12:00:00')))
│ filter ((job_type IS NULL) OR (job_type != 'AUTO CREATE STATS')) AND ((finished IS NULL) OR (finished > (now() - '12:00:00')))
└── virtual table · ·
· source ·

Expand Down
1 change: 1 addition & 0 deletions pkg/sql/parser/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ func TestContextualHelp(t *testing.T) {
{`SHOW TRACE FOR SESSION ??`, `SHOW TRACE`},
{`SHOW TRACE FOR ??`, `SHOW TRACE`},

{`SHOW JOB ??`, `SHOW JOBS`},
{`SHOW JOBS ??`, `SHOW JOBS`},
{`SHOW AUTOMATIC JOBS ??`, `SHOW JOBS`},

Expand Down
7 changes: 7 additions & 0 deletions pkg/sql/parser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ func TestParse(t *testing.T) {
{`EXPLAIN RESUME JOBS SELECT a`},
{`PAUSE JOBS SELECT a`},
{`EXPLAIN PAUSE JOBS SELECT a`},
{`SHOW JOBS SELECT a`},
{`EXPLAIN SHOW JOBS SELECT a`},

{`EXPLAIN SELECT 1`},
{`EXPLAIN EXPLAIN SELECT 1`},
Expand Down Expand Up @@ -1746,8 +1748,13 @@ func TestParse2(t *testing.T) {
`DEALLOCATE ALL`},

{`CANCEL JOB a`, `CANCEL JOBS VALUES (a)`},
{`EXPLAIN CANCEL JOB a`, `EXPLAIN CANCEL JOBS VALUES (a)`},
{`RESUME JOB a`, `RESUME JOBS VALUES (a)`},
{`EXPLAIN RESUME JOB a`, `EXPLAIN RESUME JOBS VALUES (a)`},
{`PAUSE JOB a`, `PAUSE JOBS VALUES (a)`},
{`EXPLAIN PAUSE JOB a`, `EXPLAIN PAUSE JOBS VALUES (a)`},
{`SHOW JOB a`, `SHOW JOBS VALUES (a)`},
{`EXPLAIN SHOW JOB a`, `EXPLAIN SHOW JOBS VALUES (a)`},
{`CANCEL QUERY a`, `CANCEL QUERIES VALUES (a)`},
{`CANCEL QUERY IF EXISTS a`, `CANCEL QUERIES IF EXISTS VALUES (a)`},
{`CANCEL SESSION a`, `CANCEL SESSIONS VALUES (a)`},
Expand Down
35 changes: 26 additions & 9 deletions pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ func newNameFromStr(s string) *tree.Name {
%type <tree.ComparisonOperator> sub_type
%type <tree.Expr> numeric_only
%type <tree.AliasClause> alias_clause opt_alias_clause
%type <bool> opt_ordinality opt_compact opt_automatic
%type <bool> opt_ordinality opt_compact
%type <*tree.Order> sortby
%type <tree.IndexElem> index_elem create_as_param
%type <tree.TableExpr> table_ref func_table
Expand Down Expand Up @@ -3513,18 +3513,35 @@ opt_cluster:

// %Help: SHOW JOBS - list background jobs
// %Category: Misc
// %Text: SHOW [AUTOMATIC] JOBS
// %Text:
// SHOW [AUTOMATIC] JOBS
// SHOW JOB <jobid>
// %SeeAlso: CANCEL JOBS, PAUSE JOBS, RESUME JOBS
show_jobs_stmt:
SHOW opt_automatic JOBS
SHOW AUTOMATIC JOBS
{
$$.val = &tree.ShowJobs{Automatic: $2.bool()}
$$.val = &tree.ShowJobs{Automatic: true}
}
| SHOW opt_automatic JOBS error // SHOW HELP: SHOW JOBS

opt_automatic:
AUTOMATIC { $$.val = true }
| /* EMPTY */ { $$.val = false }
| SHOW JOBS
{
$$.val = &tree.ShowJobs{Automatic: false}
}
| SHOW AUTOMATIC JOBS error // SHOW HELP: SHOW JOBS
| SHOW JOBS error // SHOW HELP: SHOW JOBS
| SHOW JOBS select_stmt
{
$$.val = &tree.ShowJobs{Jobs: $3.slct()}
}
| SHOW JOBS select_stmt error // SHOW HELP: SHOW JOBS
| SHOW JOB a_expr
{
$$.val = &tree.ShowJobs{
Jobs: &tree.Select{
Select: &tree.ValuesClause{Rows: []tree.Exprs{tree.Exprs{$3.expr()}}},
},
}
}
| SHOW JOB error // SHOW HELP: SHOW JOBS

// %Help: SHOW TRACE - display an execution trace
// %Category: Misc
Expand Down
6 changes: 6 additions & 0 deletions pkg/sql/sem/tree/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ func (node *ShowQueries) Format(ctx *FmtCtx) {

// ShowJobs represents a SHOW JOBS statement
type ShowJobs struct {
// If non-nil, a select statement that provides the job ids to be shown.
Jobs *Select
// If Automatic is true, show only automatically-generated jobs such
// as automatic CREATE STATISTICS jobs. If Automatic is false, show
// only non-automatically-generated jobs.
Expand All @@ -206,6 +208,10 @@ func (node *ShowJobs) Format(ctx *FmtCtx) {
ctx.WriteString("AUTOMATIC ")
}
ctx.WriteString("JOBS")
if node.Jobs != nil {
ctx.WriteString(" ")
ctx.FormatNode(node.Jobs)
}
}

// ShowSessions represents a SHOW SESSIONS statement
Expand Down
30 changes: 30 additions & 0 deletions pkg/sql/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,36 @@ func TestShowAutomaticJobs(t *testing.T) {
}

var out row

sqlDB.QueryRow(t, `SELECT job_id, job_type FROM [SHOW JOB 1]`).Scan(&out.id, &out.typ)
if out.id != 1 || out.typ != "CREATE STATS" {
t.Fatalf("Expected id:%d and type:%s but found id:%d and type:%s",
1, "CREATE STATS", out.id, out.typ)
}

sqlDB.QueryRow(t, `SELECT job_id, job_type FROM [SHOW JOBS SELECT 1]`).Scan(&out.id, &out.typ)
if out.id != 1 || out.typ != "CREATE STATS" {
t.Fatalf("Expected id:%d and type:%s but found id:%d and type:%s",
1, "CREATE STATS", out.id, out.typ)
}

sqlDB.QueryRow(t, `SELECT job_id, job_type FROM [SHOW JOBS (SELECT 1)]`).Scan(&out.id, &out.typ)
if out.id != 1 || out.typ != "CREATE STATS" {
t.Fatalf("Expected id:%d and type:%s but found id:%d and type:%s",
1, "CREATE STATS", out.id, out.typ)
}
sqlDB.QueryRow(t, `SELECT job_id, job_type FROM [SHOW JOB 2]`).Scan(&out.id, &out.typ)
if out.id != 2 || out.typ != "AUTO CREATE STATS" {
t.Fatalf("Expected id:%d and type:%s but found id:%d and type:%s",
2, "AUTO CREATE STATS", out.id, out.typ)
}

sqlDB.QueryRow(t, `SELECT job_id, job_type FROM [SHOW JOBS SELECT 2]`).Scan(&out.id, &out.typ)
if out.id != 2 || out.typ != "AUTO CREATE STATS" {
t.Fatalf("Expected id:%d and type:%s but found id:%d and type:%s",
2, "AUTO CREATE STATS", out.id, out.typ)
}

sqlDB.QueryRow(t, `SELECT job_id, job_type FROM [SHOW JOBS]`).Scan(&out.id, &out.typ)
if out.id != 1 || out.typ != "CREATE STATS" {
t.Fatalf("Expected id:%d and type:%s but found id:%d and type:%s",
Expand Down

0 comments on commit a78892f

Please sign in to comment.