diff --git a/pkg/cli/clisqlclient/copy.go b/pkg/cli/clisqlclient/copy.go index 733aaaefeba6..7e2b57d72fee 100644 --- a/pkg/cli/clisqlclient/copy.go +++ b/pkg/cli/clisqlclient/copy.go @@ -96,10 +96,13 @@ func (c *CopyFromState) Commit(ctx context.Context, cleanupFunc func(), lines st return func(ctx context.Context, conn Conn) (Rows, bool, error) { defer cleanupFunc() rows, isMulti, err := func() (Rows, bool, error) { - for _, l := range strings.Split(lines, "\n") { - _, err := c.copyFromer.CopyData(ctx, l) - if err != nil { - return nil, false, err + // Do not send anything if it is just an empty string. + if lines != "" { + for _, l := range strings.Split(lines, "\n") { + _, err := c.copyFromer.CopyData(ctx, l) + if err != nil { + return nil, false, err + } } } r, err := c.copyFromer.Exec(nil) diff --git a/pkg/cli/clisqlshell/sql.go b/pkg/cli/clisqlshell/sql.go index a31814774380..756fb8666a85 100644 --- a/pkg/cli/clisqlshell/sql.go +++ b/pkg/cli/clisqlshell/sql.go @@ -974,6 +974,7 @@ func (c *cliState) doStartLine(nextState cliStateEnum) cliStateEnum { c.atEOF = false c.partialLines = c.partialLines[:0] c.partialStmtsLen = 0 + c.concatLines = "" c.useContinuePrompt = false @@ -1243,7 +1244,8 @@ func (c *cliState) doHandleCliCmd(loopState, nextState cliStateEnum) cliStateEnu case `\.`: if c.inCopy() { - c.concatLines += "\n" + `\.` + c.partialLines = append(c.partialLines, `\.`) + c.partialStmtsLen++ return cliRunStatement } return c.invalidSyntax(errState) @@ -1602,7 +1604,7 @@ func (c *cliState) doPrepareStatementLine( (c.inCopy() && (strings.HasSuffix(c.concatLines, "\n"+`\.`) || c.atEOF)) || // We're always at the end of a statement if EOF is reached in the // single statement mode. - c.singleStatement && c.atEOF + (c.singleStatement && c.atEOF) if c.atEOF { // Definitely no more input expected. if !endOfStmt { diff --git a/pkg/cli/interactive_tests/test_copy.tcl b/pkg/cli/interactive_tests/test_copy.tcl index de3362ba7d60..1a0713bd2aa4 100644 --- a/pkg/cli/interactive_tests/test_copy.tcl +++ b/pkg/cli/interactive_tests/test_copy.tcl @@ -28,6 +28,22 @@ eexpect "could not parse" end_test +start_test "check EMPTY copy" + +send "COPY t FROM STDIN;\r" +eexpect ">>" +send_eof +eexpect "COPY 0" +eexpect root@ + +send "COPY t FROM STDIN;\r" +eexpect ">>" +send "\\.\r" +eexpect "COPY 0" +eexpect root@ + +end_test + start_test "multi statement with COPY" send "SELECT 1; COPY t FROM STDIN CSV;\r" eexpect "COPY together with other statements in a query string is not supported"