Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli/sql: new parameter --watch to repeat the -e statements #40594

Merged
merged 1 commit into from
Sep 19, 2019
Merged
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
18 changes: 18 additions & 0 deletions pkg/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,24 @@ func Example_sql() {
// invalid syntax
}

func Example_sql_watch() {
c := newCLITest(cliTestParams{})
defer c.cleanup()

c.RunWithArgs([]string{`sql`, `-e`, `create table d(x int); insert into d values(3)`})
c.RunWithArgs([]string{`sql`, `--watch`, `.1s`, `-e`, `update d set x=x-1 returning 1/x as dec`})

// Output:
// sql -e create table d(x int); insert into d values(3)
// INSERT 1
// sql --watch .1s -e update d set x=x-1 returning 1/x as dec
// dec
// 0.5
// dec
// 1
// pq: division by zero
}

func Example_sql_format() {
c := newCLITest(cliTestParams{})
defer c.cleanup()
Expand Down
8 changes: 8 additions & 0 deletions pkg/cli/cliflags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,14 @@ with a non-zero status code and further statements are not executed. The
results of each SQL statement are printed on the standard output.`,
}

Watch = FlagInfo{
Name: "watch",
Description: `
Repeat the SQL statement(s) specified with --execute
with the specified period. The client will stop watching
if an execution of the SQL statement(s) fail.`,
}

EchoSQL = FlagInfo{
Name: "echo-sql",
Description: `
Expand Down
6 changes: 6 additions & 0 deletions pkg/cli/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func initCLIDefaults() {

sqlCtx.setStmts = nil
sqlCtx.execStmts = nil
sqlCtx.repeatDelay = 0
sqlCtx.safeUpdates = false
sqlCtx.showTimes = false
sqlCtx.debugMode = false
Expand Down Expand Up @@ -217,6 +218,11 @@ var sqlCtx = struct {
// execStmts is a list of statements to execute.
execStmts statementsValue

// repeatDelay indicates that the execStmts should be "watched"
// at the specified time interval. Zero disables
// the watch.
repeatDelay time.Duration

// safeUpdates indicates whether to set sql_safe_updates in the CLI
// shell.
safeUpdates bool
Expand Down
1 change: 1 addition & 0 deletions pkg/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ func init() {
f := cmd.Flags()
VarFlag(f, &sqlCtx.setStmts, cliflags.Set)
VarFlag(f, &sqlCtx.execStmts, cliflags.Execute)
DurationFlag(f, &sqlCtx.repeatDelay, cliflags.Watch, sqlCtx.repeatDelay)
BoolFlag(f, &sqlCtx.safeUpdates, cliflags.SafeUpdates, sqlCtx.safeUpdates)
BoolFlag(f, &sqlCtx.debugMode, cliflags.CliDebugMode, sqlCtx.debugMode)
}
Expand Down
38 changes: 24 additions & 14 deletions pkg/cli/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"sort"
"strconv"
"strings"
"time"

"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/cli/cliflags"
Expand Down Expand Up @@ -1389,22 +1390,31 @@ func runInteractive(conn *sqlConn) (exitErr error) {
// runOneStatement executes one statement and terminates
// on error.
func (c *cliState) runStatements(stmts []string) error {
for i, stmt := range stmts {
// We do not use the logic from doRunStatement here
// because we need a different error handling mechanism:
// the error, if any, must not be printed to stderr if
// we are returning directly.
c.exitErr = runQueryAndFormatResults(c.conn, os.Stdout, makeQuery(stmt))
if c.exitErr != nil {
if !c.errExit && i < len(stmts)-1 {
// Print the error now because we don't get a chance later.
fmt.Fprintln(stderr, c.exitErr)
maybeShowErrorDetails(stderr, c.exitErr, false)
}
if c.errExit {
break
for {
for i, stmt := range stmts {
// We do not use the logic from doRunStatement here
// because we need a different error handling mechanism:
// the error, if any, must not be printed to stderr if
// we are returning directly.
c.exitErr = runQueryAndFormatResults(c.conn, os.Stdout, makeQuery(stmt))
if c.exitErr != nil {
if !c.errExit && i < len(stmts)-1 {
// Print the error now because we don't get a chance later.
fmt.Fprintln(stderr, c.exitErr)
maybeShowErrorDetails(stderr, c.exitErr, false)
}
if c.errExit {
break
}
}
}
// If --watch was specified and no error was encountered,
// repeat.
if sqlCtx.repeatDelay > 0 && c.exitErr == nil {
time.Sleep(sqlCtx.repeatDelay)
continue
}
break
}

if c.exitErr != nil {
Expand Down