Skip to content
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
55 changes: 24 additions & 31 deletions go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -895,27 +895,23 @@ func (node *Load) walkSubtree(visit Visit) error {

type Fields struct {
TerminatedBy *SQLVal
*EnclosedBy
EscapedBy *SQLVal
EnclosedBy *EnclosedBy
EscapedBy *SQLVal
SQLNode
}

func (node *Fields) Format(buf *TrackedBuffer) {
if node == nil {
return
}

terminated := ""
buf.Myprintf(" fields")
if node.TerminatedBy != nil {
terminated = "terminated by " + "'" + string(node.TerminatedBy.Val) + "'"
buf.Myprintf(" terminated by '%s'", node.TerminatedBy.Val)
}

escaped := ""
buf.Myprintf("%v", node.EnclosedBy)
if node.EscapedBy != nil {
escaped = " escaped by " + "'" + string(node.EscapedBy.Val) + "'"
buf.Myprintf(" escaped by '%s'", node.EscapedBy.Val)
}

buf.Myprintf(" fields %s%v%s", terminated, node.EnclosedBy, escaped)
}

type EnclosedBy struct {
Expand All @@ -928,15 +924,10 @@ func (node *EnclosedBy) Format(buf *TrackedBuffer) {
if node == nil {
return
}

enclosed := "enclosed by " + "'" + string(node.Delim.Val) + "'"
if node.Optionally {
enclosed = " optionally " + enclosed
} else {
enclosed = " " + enclosed
buf.Myprintf(" optionally")
}

buf.Myprintf(enclosed)
buf.Myprintf(" enclosed by '%s'", node.Delim.Val)
}

type Lines struct {
Expand All @@ -949,18 +940,13 @@ func (node *Lines) Format(buf *TrackedBuffer) {
if node == nil {
return
}

starting := ""
buf.Myprintf(" lines")
if node.StartingBy != nil {
starting = " starting by " + "'" + string(node.StartingBy.Val) + "'"
buf.Myprintf(" starting by '%s'", node.StartingBy.Val)
}

terminated := ""
if node.TerminatedBy != nil {
terminated = " terminated by " + "'" + string(node.TerminatedBy.Val) + "'"
buf.Myprintf(" terminated by '%s'", node.TerminatedBy.Val)
}

buf.Myprintf(" lines%s%s", starting, terminated)
}

// BeginEndBlock represents a BEGIN .. END block with one or more statements nested within
Expand Down Expand Up @@ -4316,8 +4302,12 @@ func (w *With) walkSubtree(visit Visit) error {

type Into struct {
Variables Variables
Outfile string
Dumpfile string

Outfile string
Charset string
Fields *Fields
Lines *Lines
}

func (i *Into) Format(buf *TrackedBuffer) {
Expand All @@ -4326,14 +4316,17 @@ func (i *Into) Format(buf *TrackedBuffer) {
}

buf.Myprintf(" into ")
if i.Variables != nil {
buf.Myprintf("%v", i.Variables)
buf.Myprintf("%v", i.Variables)
if i.Dumpfile != "" {
buf.Myprintf("dumpfile '%s'", i.Dumpfile)
}
if i.Outfile != "" {
buf.Myprintf("outfile '%s'", i.Outfile)
}
if i.Dumpfile != "" {
buf.Myprintf("dumpfile '%s'", i.Dumpfile)
if i.Charset != "" {
buf.Myprintf(" character set %s", i.Charset)
}
buf.Myprintf("%v", i.Fields)
buf.Myprintf("%v", i.Lines)
}
}

Expand Down
115 changes: 109 additions & 6 deletions go/vt/sqlparser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3208,22 +3208,75 @@ var (
}, {
input: "SELECT id FROM mytable UNION select id FROM testtable UNION select id FROM othertable LIMIT 1 INTO @myId",
output: "select id from mytable union select id from testtable union select id from othertable limit 1 into @myId",
}, {
},
{
input: "SELECT 1 INTO OUTFILE 'x.txt'",
output: "select 1 into outfile 'x.txt'",
}, {
},
{
input: "SELECT * FROM (VALUES ROW(2,4,8),ROW(1,2,3)) AS t(a,b,c) INTO OUTFILE 'myfile.txt'",
output: "select * from (values row(2, 4, 8), row(1, 2, 3)) as t (a, b, c) into outfile 'myfile.txt'",
}, {
},
{
input: "SELECT id INTO OUTFILE 'myfile.txt' FROM mytable ORDER BY id DESC",
output: "select id from mytable order by id desc into outfile 'myfile.txt'",
}, {
},
{
input: "SELECT * FROM (VALUES ROW(2,4,8)) AS t INTO DUMPFILE 'even.dump'",
output: "select * from (values row(2, 4, 8)) as t into dumpfile 'even.dump'",
}, {
},
{
input: "SELECT id INTO DUMPFILE 'dump.txt' FROM mytable ORDER BY id DESC LIMIT 15",
output: "select id from mytable order by id desc limit 15 into dumpfile 'dump.txt'",
}, {
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a'",
},
{
input: "select * from tbl into outfile 'outfile.txt' columns terminated by 'a'",
output: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' enclosed by 'b'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' optionally enclosed by 'b'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' escaped by 'c'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' enclosed by 'b' escaped by 'c'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' optionally enclosed by 'b' escaped by 'c'",
},
{
input: "select * from tbl into outfile 'outfile.txt' lines terminated by 'd'",
},
{
input: "select * from tbl into outfile 'outfile.txt' lines starting by 'd' terminated by 'e'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' lines terminated by 'd'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' enclosed by 'b' lines terminated by 'd'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' escaped by 'c' lines terminated by 'd'",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' optionally enclosed by 'b' escaped by 'c' lines terminated by 'd'",
},
{
input: "select * from tbl into outfile 'outfile.txt' character set binary fields terminated by 'a'",
},
{
input: "table tbl into outfile 'outfile.txt' fields terminated by 'a' optionally enclosed by 'b' escaped by 'c' lines terminated by 'd'",
output: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' optionally enclosed by 'b' escaped by 'c' lines terminated by 'd'",
},
{
input: "CREATE PROCEDURE proc (IN p_store_id INT, OUT current INT) SELECT COUNT(*) INTO current FROM inventory WHERE store_id = p_store_id",
output: "create procedure proc (in p_store_id INT, out current INT) select COUNT(*) from inventory where store_id = p_store_id into `current`",
}, {
Expand Down Expand Up @@ -4662,6 +4715,56 @@ func TestInvalid(t *testing.T) {
input: "select sql_cache sql_no_cache * from t",
err: "incorrect usage of SQL_CACHE and SQL_NO_CACHE",
},
{
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' fields terminated by 'a'",
err: "syntax error",
},
{
input: "select * from tbl into outfile 'outfile.txt' enclosed by 'b'",
err: "syntax error",
},
{
input: "select * from tbl into outfile 'outfile.txt' escaped by 'c'",
err: "syntax error",
},
{
input: "select * from tbl into outfile 'outfile.txt' enclosed by 'b' fields terminated by 'a'",
err: "syntax error",
},
{
input: "select * from tbl into outfile 'outfile.txt' escaped by 'c' fields terminated by 'a'",
err: "syntax error",
},
{
input: "select * from tbl into outfile 'outfile.txt' lines terminated by 'd' fields terminated by 'a'",
err: "syntax error",
},

{
// TODO: should work
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' enclosed by 'b' enclosed by 'b'",
err: "syntax error",
},
{
// TODO: should work
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' optionally enclosed by 'b' optionally enclosed by 'b'",
err: "syntax error",
},
{
// TODO: should work
input: "select * from tbl into outfile 'outfile.txt' fields terminated by 'a' escaped by 'c' escaped by 'c'",
err: "syntax error",
},
{
// TODO: should work
input: "select * from tbl into outfile 'outfile.txt' lines terminated by 'e' starting by 'd'",
err: "syntax error",
},
{
// TODO: should work
input: "select * from tbl into outfile 'outfile.txt' lines starting by 'd' terminated by 'e' starting by 'd' terminated by 'e'",
err: "syntax error",
},
}

for _, tcase := range invalidSQL {
Expand Down
Loading