Skip to content

Commit

Permalink
return ok result for select into statements (#2781)
Browse files Browse the repository at this point in the history
  • Loading branch information
jycor authored Dec 5, 2024
1 parent 6ffe4b8 commit dc32026
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 49 deletions.
99 changes: 60 additions & 39 deletions enginetest/enginetests.go
Original file line number Diff line number Diff line change
Expand Up @@ -1017,44 +1017,50 @@ func TestSelectIntoFile(t *testing.T, harness Harness) {
})

tests := []struct {
file string
query string
exp string
err *errors.Kind
skip bool
file string
query string
exp string
expRows []sql.Row
err *errors.Kind
skip bool
}{
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1\tfirst row\n" +
"2\tsecond row\n" +
"3\tthird row\n",
},
{
file: "dumpfile.txt",
query: "select * from mytable limit 1 into dumpfile 'dumpfile.txt';",
exp: "1first row",
file: "dumpfile.txt",
query: "select * from mytable limit 1 into dumpfile 'dumpfile.txt';",
expRows: []sql.Row{{types.NewOkResult(1)}},
exp: "1first row",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1,first row\n" +
"2,second row\n" +
"3,third row\n",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by '$$';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by '$$';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1$$first row\n" +
"2$$second row\n" +
"3$$third row\n",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' optionally enclosed by '\"';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' optionally enclosed by '\"';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1,\"first row\"\n" +
"2,\"second row\"\n" +
Expand All @@ -1071,56 +1077,63 @@ func TestSelectIntoFile(t *testing.T, harness Harness) {
err: sql.ErrUnexpectedSeparator,
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' enclosed by '\"';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' enclosed by '\"';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"\"1\",\"first row\"\n" +
"\"2\",\"second row\"\n" +
"\"3\",\"third row\"\n",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by ';';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by ';';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1,first row;" +
"2,second row;" +
"3,third row;",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by 'r';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by 'r';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1,fi\\rst \\rowr" +
"2,second \\rowr" +
"3,thi\\rd \\rowr",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines starting by 'r';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines starting by 'r';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"r1,first row\n" +
"r2,second row\n" +
"r3,third row\n",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by '';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by '';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1\tfirst row\n" +
"2\tsecond row\n" +
"3\tthird row\n",
},
{
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by '';",
file: "outfile.txt",
query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by '';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1,first row" +
"2,second row" +
"3,third row",
},
{
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt';",
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt';",
expRows: []sql.Row{{types.NewOkResult(6)}},
exp: "1\t\\N\t\\N\t\\N\n" +
"2\t2\t1\t\\N\n" +
"3\t\\N\t0\t\\N\n" +
Expand All @@ -1129,8 +1142,9 @@ func TestSelectIntoFile(t *testing.T, harness Harness) {
"6\t6\t0\t6\n",
},
{
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' enclosed by '\"';",
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' enclosed by '\"';",
expRows: []sql.Row{{types.NewOkResult(6)}},
exp: "\"1\",\\N,\\N,\\N\n" +
"\"2\",\"2\",\"1\",\\N\n" +
"\"3\",\\N,\"0\",\\N\n" +
Expand All @@ -1139,8 +1153,9 @@ func TestSelectIntoFile(t *testing.T, harness Harness) {
"\"6\",\"6\",\"0\",\"6\"\n",
},
{
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' escaped by '$';",
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' escaped by '$';",
expRows: []sql.Row{{types.NewOkResult(6)}},
exp: "1,$N,$N,$N\n" +
"2,2,1,$N\n" +
"3,$N,0,$N\n" +
Expand All @@ -1149,8 +1164,9 @@ func TestSelectIntoFile(t *testing.T, harness Harness) {
"6,6,0,6\n",
},
{
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' escaped by '';",
file: "outfile.txt",
query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' escaped by '';",
expRows: []sql.Row{{types.NewOkResult(6)}},
exp: "1,NULL,NULL,NULL\n" +
"2,2,1,NULL\n" +
"3,NULL,0,NULL\n" +
Expand All @@ -1159,8 +1175,9 @@ func TestSelectIntoFile(t *testing.T, harness Harness) {
"6,6,0,6\n",
},
{
file: "./subdir/outfile.txt",
query: "select * from mytable into outfile './subdir/outfile.txt';",
file: "./subdir/outfile.txt",
query: "select * from mytable into outfile './subdir/outfile.txt';",
expRows: []sql.Row{{types.NewOkResult(3)}},
exp: "" +
"1\tfirst row\n" +
"2\tsecond row\n" +
Expand Down Expand Up @@ -1198,7 +1215,11 @@ func TestSelectIntoFile(t *testing.T, harness Harness) {
}
// in case there are any residual files from previous runs
os.Remove(tt.file)
TestQueryWithContext(t, ctx, e, harness, tt.query, nil, nil, nil, nil)
var expected = tt.expRows
if IsServerEngine(e) {
expected = nil
}
TestQueryWithContext(t, ctx, e, harness, tt.query, expected, types.OkResultSchema, nil, nil)
res, err := os.ReadFile(tt.file)
require.NoError(t, err)
require.Equal(t, tt.exp, string(res))
Expand Down
9 changes: 4 additions & 5 deletions enginetest/queries/script_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -1623,11 +1623,10 @@ CREATE TABLE tab3 (
},
Assertions: []ScriptTestAssertion{
{
// SELECT INTO has an empty result schema
// https://github.com/dolthub/dolt/issues/6105
Query: `SELECT 1 INTO @abc`,
Expected: []sql.Row{{}},
ExpectedColumns: nil,
Query: `SELECT 1 INTO @abc`,
SkipResultCheckOnServerEngine: true,
Expected: []sql.Row{{types.NewOkResult(1)}},
ExpectedColumns: nil,
},
{
Query: `SELECT @abc`,
Expand Down
3 changes: 2 additions & 1 deletion sql/plan/into.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"strings"

"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/types"
)

// Into is a node to wrap the top-level node in a query plan so that any result will set user-defined or others
Expand Down Expand Up @@ -79,7 +80,7 @@ var emptySch = make(sql.Schema, 0)
func (i *Into) Schema() sql.Schema {
// SELECT INTO does not return results directly (only through SQL vars or files),
// so it's result schema is always empty.
return emptySch
return types.OkResultSchema
}

func (i *Into) IsReadOnly() bool {
Expand Down
8 changes: 4 additions & 4 deletions sql/rowexec/rel.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ func (b *BaseBuilder) buildInto(ctx *sql.Context, n *plan.Into, row sql.Row) (sq
}
file.WriteString(n.LinesTerminatedBy)
}
return sql.RowsToRowIter(sql.Row{}), nil
return sql.RowsToRowIter(sql.Row{types.NewOkResult(len(rows))}), nil
}

rowNum := len(rows)
Expand All @@ -652,12 +652,12 @@ func (b *BaseBuilder) buildInto(ctx *sql.Context, n *plan.Into, row sql.Row) (sq
file.WriteString(fmt.Sprintf("%v", val))
}
}
return sql.RowsToRowIter(sql.Row{}), nil
return sql.RowsToRowIter(sql.Row{types.NewOkResult(rowNum)}), nil
}

if rowNum == 0 {
// a warning with error code 1329 occurs (No data), and make no change to variables
return sql.RowsToRowIter(sql.Row{}), nil
return sql.RowsToRowIter(sql.Row{types.NewOkResult(0)}), nil
}
if len(rows[0]) != len(n.IntoVars) {
return nil, sql.ErrColumnNumberDoesNotMatch.New()
Expand All @@ -684,7 +684,7 @@ func (b *BaseBuilder) buildInto(ctx *sql.Context, n *plan.Into, row sql.Row) (sq
}
}

return sql.RowsToRowIter(sql.Row{}), nil
return sql.RowsToRowIter(sql.Row{types.NewOkResult(1)}), nil
}

func (b *BaseBuilder) buildExternalProcedure(ctx *sql.Context, n *plan.ExternalProcedure, row sql.Row) (sql.RowIter, error) {
Expand Down

0 comments on commit dc32026

Please sign in to comment.