github.com/dolthub/go-mysql-server@v0.18.0/sql/planbuilder/load.go (about) 1 // Copyright 2023 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 planbuilder 16 17 import ( 18 "fmt" 19 "strings" 20 21 ast "github.com/dolthub/vitess/go/vt/sqlparser" 22 23 "github.com/dolthub/go-mysql-server/sql" 24 "github.com/dolthub/go-mysql-server/sql/plan" 25 ) 26 27 func (b *Builder) buildLoad(inScope *scope, d *ast.Load) (outScope *scope) { 28 dbName := strings.ToLower(d.Table.Qualifier.String()) 29 if dbName == "" { 30 dbName = b.ctx.GetCurrentDatabase() 31 } 32 33 tableName := strings.ToLower(d.Table.Name.String()) 34 destScope, ok := b.buildResolvedTable(inScope, dbName, tableName, nil) 35 if !ok { 36 b.handleErr(sql.ErrTableNotFound.New(tableName)) 37 } 38 var db sql.Database 39 var rt *plan.ResolvedTable 40 switch n := destScope.node.(type) { 41 case *plan.ResolvedTable: 42 rt = n 43 db = rt.Database() 44 case *plan.UnresolvedTable: 45 db = n.Database() 46 default: 47 b.handleErr(fmt.Errorf("expected insert destination to be resolved or unresolved table")) 48 } 49 if rt == nil { 50 if b.TriggerCtx().Active && !b.TriggerCtx().Call { 51 b.TriggerCtx().UnresolvedTables = append(b.TriggerCtx().UnresolvedTables, tableName) 52 } else { 53 err := fmt.Errorf("expected resolved table: %s", tableName) 54 b.handleErr(err) 55 } 56 } 57 58 var ignoreNumVal int64 = 0 59 if d.IgnoreNum != nil { 60 ignoreNumVal = b.getInt64Value(inScope, d.IgnoreNum, "Cannot parse ignore Value") 61 } 62 63 dest := destScope.node 64 sch := dest.Schema() 65 if rt != nil { 66 sch = b.resolveSchemaDefaults(destScope, rt.Schema()) 67 } 68 69 ld := plan.NewLoadData(bool(d.Local), d.Infile, sch, columnsToStrings(d.Columns), ignoreNumVal, d.IgnoreOrReplace) 70 71 if d.Charset != "" { 72 // TODO: deal with charset; ignore for now 73 ld.Charset = d.Charset 74 } 75 76 if d.Fields != nil { 77 if d.Fields.TerminatedBy != nil && len(d.Fields.TerminatedBy.Val) != 0 { 78 ld.FieldsTerminatedBy = string(d.Fields.TerminatedBy.Val) 79 } 80 81 if d.Fields.EnclosedBy != nil { 82 ld.FieldsEnclosedBy = string(d.Fields.EnclosedBy.Delim.Val) 83 if len(ld.FieldsEnclosedBy) > 1 { 84 b.handleErr(sql.ErrUnexpectedSeparator.New()) 85 } 86 if d.Fields.EnclosedBy.Optionally { 87 ld.FieldsEnclosedByOpt = true 88 } 89 } 90 91 if d.Fields.EscapedBy != nil { 92 ld.FieldsEscapedBy = string(d.Fields.EscapedBy.Val) 93 if len(ld.FieldsEscapedBy) > 1 { 94 b.handleErr(sql.ErrUnexpectedSeparator.New()) 95 } 96 } 97 } 98 99 if d.Lines != nil { 100 if d.Lines.StartingBy != nil { 101 ld.LinesStartingBy = string(d.Lines.StartingBy.Val) 102 } 103 if d.Lines.TerminatedBy != nil { 104 ld.LinesTerminatedBy = string(d.Lines.TerminatedBy.Val) 105 } 106 } 107 108 outScope = inScope.push() 109 ins := plan.NewInsertInto(db, plan.NewInsertDestination(sch, dest), ld, ld.IsReplace, ld.ColumnNames, nil, ld.IsIgnore) 110 b.validateInsert(ins) 111 outScope.node = ins 112 if rt != nil { 113 checks := b.loadChecksFromTable(destScope, rt.Table) 114 outScope.node = ins.WithChecks(checks) 115 } 116 return outScope 117 }