Skip to content

Commit

Permalink
Merge pull request cockroachdb#19364 from knz/20171019-help-user
Browse files Browse the repository at this point in the history
cli/sql: help users who enter a single '?' further
  • Loading branch information
knz authored Oct 20, 2017
2 parents ac51df3 + b8e8dfa commit b18e300
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
12 changes: 12 additions & 0 deletions pkg/cli/interactive_tests/test_contextual_help.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ eexpect "See also"
eexpect root@
end_test

start_test "Check that a useful reminder is given if the user mistakenly uses a single ?."
send "select ?\r"
eexpect "Note:"
eexpect JSON
eexpect "use '??'"
eexpect " ->"
# restore the normal state
send ";\r"
eexpect HINT
eexpect root@
end_test


start_test "Check that ??-tab works."
send "select ??\t"
Expand Down
19 changes: 14 additions & 5 deletions pkg/cli/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,15 +327,19 @@ func (c *cliState) handleUnset(args []string, nextState, errState cliStateEnum)
return nextState
}

func isEndOfStatement(fullStmt string) (isEmpty, isEnd bool) {
func checkTokens(fullStmt string) (isEmpty bool, lastTok int) {
sc := parser.MakeScanner(fullStmt)
isEmpty = true
var last int
sc.Tokens(func(t int) {
isEmpty = false
last = t
})
return isEmpty, last == ';' || last == parser.HELPTOKEN
return isEmpty, last
}

func isEndOfStatement(lastTok int) bool {
return lastTok == ';' || lastTok == parser.HELPTOKEN
}

// handleHelp prints SQL help.
Expand Down Expand Up @@ -849,7 +853,8 @@ func (c *cliState) doPrepareStatementLine(
return startState
}

isEmpty, endsWithSemi := isEndOfStatement(c.concatLines)
isEmpty, lastTok := checkTokens(c.concatLines)
endOfStmt := isEndOfStatement(lastTok)
if c.partialStmtsLen == 0 && isEmpty {
// More whitespace, or comments. Still nothing to do. However
// if the syntax was non-trivial to arrive here,
Expand All @@ -861,14 +866,18 @@ func (c *cliState) doPrepareStatementLine(
}
if c.atEOF {
// Definitely no more input expected.
if !endsWithSemi {
if !endOfStmt {
fmt.Fprintf(stderr, "missing semicolon at end of statement: %s\n", c.concatLines)
c.exitErr = fmt.Errorf("last statement was not executed: %s", c.concatLines)
return cliStop
}
}

if !endsWithSemi {
if !endOfStmt {
if lastTok == '?' {
fmt.Fprintf(c.ins.Stdout(),
"Note: a single '?' is a JSON operator. If you want contextual help, use '??'.\n")
}
return contState
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/cli/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,11 @@ func TestIsEndOfStatement(t *testing.T) {
}

for _, test := range tests {
isEmpty, isEnd := isEndOfStatement(test.in)
isEmpty, lastTok := checkTokens(test.in)
if isEmpty != test.isEmpty {
t.Errorf("%q: isEmpty expected %v, got %v", test.in, test.isEmpty, isEmpty)
}
isEnd := isEndOfStatement(lastTok)
if isEnd != test.isEnd {
t.Errorf("%q: isEnd expected %v, got %v", test.in, test.isEnd, isEnd)
}
Expand Down

0 comments on commit b18e300

Please sign in to comment.