github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/into.go (about) 1 // Copyright 2022 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plan 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/dolthub/go-mysql-server/sql" 22 ) 23 24 // Into is a node to wrap the top-level node in a query plan so that any result will set user-defined or others 25 // variables given 26 type Into struct { 27 UnaryNode 28 IntoVars []sql.Expression 29 Dumpfile string 30 Outfile string 31 32 Charset string 33 34 FieldsTerminatedBy string 35 FieldsEnclosedBy string 36 FieldsEnclosedByOpt bool 37 FieldsEscapedBy string 38 39 LinesStartingBy string 40 LinesTerminatedBy string 41 } 42 43 var _ sql.Node = (*Into)(nil) 44 var _ sql.CollationCoercible = (*Into)(nil) 45 46 // Default values as defined here: https://dev.mysql.com/doc/refman/8.0/en/load-data.html 47 const ( 48 defaultFieldsTerminatedBy = "\t" 49 defaultFieldsEnclosedBy = "" 50 defaultFieldsEnclosedByOpt = false 51 defaultFieldsEscapedBy = "\\" 52 defaultLinesStartingBy = "" 53 defaultLinesTerminatedBy = "\n" 54 ) 55 56 func NewInto( 57 child sql.Node, 58 variables []sql.Expression, 59 outfile, dumpfile string) *Into { 60 return &Into{ 61 UnaryNode: UnaryNode{child}, 62 IntoVars: variables, 63 Dumpfile: dumpfile, 64 Outfile: outfile, 65 66 FieldsTerminatedBy: defaultFieldsTerminatedBy, 67 FieldsEnclosedBy: defaultFieldsEnclosedBy, 68 FieldsEnclosedByOpt: defaultFieldsEnclosedByOpt, 69 FieldsEscapedBy: defaultFieldsEscapedBy, 70 71 LinesStartingBy: defaultLinesStartingBy, 72 LinesTerminatedBy: defaultLinesTerminatedBy, 73 } 74 } 75 76 // Schema implements the Node interface. 77 func (i *Into) Schema() sql.Schema { 78 // SELECT INTO does not return results directly (only through SQL vars or files), 79 // so it's result schema is always empty. 80 return nil 81 } 82 83 func (i *Into) IsReadOnly() bool { 84 return i.Child.IsReadOnly() 85 } 86 87 func (i *Into) String() string { 88 p := sql.NewTreePrinter() 89 var vars = make([]string, len(i.IntoVars)) 90 for j, v := range i.IntoVars { 91 vars[j] = fmt.Sprintf(v.String()) 92 } 93 _ = p.WriteNode("Into(%s, Outfile %s, Dumpfile %s)", strings.Join(vars, ", "), i.Outfile, i.Dumpfile) 94 _ = p.WriteChildren(i.Child.String()) 95 return p.String() 96 } 97 98 func (i *Into) DebugString() string { 99 p := sql.NewTreePrinter() 100 var vars = make([]string, len(i.IntoVars)) 101 for j, v := range i.IntoVars { 102 vars[j] = sql.DebugString(v) 103 } 104 _ = p.WriteNode("Into(%s, Outfile %s, Dumpfile %s)", strings.Join(vars, ", "), i.Outfile, i.Dumpfile) 105 _ = p.WriteChildren(sql.DebugString(i.Child)) 106 return p.String() 107 } 108 109 func (i *Into) WithChildren(children ...sql.Node) (sql.Node, error) { 110 if len(children) != 1 { 111 return nil, sql.ErrInvalidChildrenNumber.New(i, len(children), 1) 112 } 113 ni := *i 114 ni.Child = children[0] 115 return &ni, nil 116 } 117 118 // CheckPrivileges implements the interface sql.Node. 119 func (i *Into) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 120 return i.Child.CheckPrivileges(ctx, opChecker) 121 } 122 123 // CollationCoercibility implements the interface sql.CollationCoercible. 124 func (i *Into) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 125 return sql.GetCoercibility(ctx, i.Child) 126 } 127 128 // WithExpressions implements the sql.Expressioner interface. 129 func (i *Into) WithExpressions(exprs ...sql.Expression) (sql.Node, error) { 130 if len(exprs) != len(i.IntoVars) { 131 return nil, sql.ErrInvalidChildrenNumber.New(i, len(exprs), len(i.IntoVars)) 132 } 133 ni := *i 134 ni.IntoVars = exprs 135 return &ni, nil 136 } 137 138 // Expressions implements the sql.Expressioner interface. 139 func (i *Into) Expressions() []sql.Expression { 140 return i.IntoVars 141 }