github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/load_data.go (about)

     1  // Copyright 2021 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  	"strings"
    19  
    20  	"github.com/dolthub/vitess/go/vt/sqlparser"
    21  
    22  	"github.com/dolthub/go-mysql-server/sql"
    23  )
    24  
    25  type LoadData struct {
    26  	Local              bool
    27  	File               string
    28  	DestSch            sql.Schema
    29  	ColumnNames        []string
    30  	ResponsePacketSent bool
    31  	IgnoreNum          int64
    32  	IsIgnore           bool
    33  	IsReplace          bool
    34  
    35  	Charset string
    36  
    37  	FieldsTerminatedBy  string
    38  	FieldsEnclosedBy    string
    39  	FieldsEnclosedByOpt bool
    40  	FieldsEscapedBy     string
    41  
    42  	LinesStartingBy   string
    43  	LinesTerminatedBy string
    44  }
    45  
    46  var _ sql.Node = (*LoadData)(nil)
    47  var _ sql.CollationCoercible = (*LoadData)(nil)
    48  
    49  func (l *LoadData) Resolved() bool {
    50  	return l.DestSch.Resolved()
    51  }
    52  
    53  func (l *LoadData) String() string {
    54  	pr := sql.NewTreePrinter()
    55  
    56  	_ = pr.WriteNode("LOAD DATA %s", l.File)
    57  	return pr.String()
    58  }
    59  
    60  func (l *LoadData) Schema() sql.Schema {
    61  	return l.DestSch
    62  }
    63  
    64  func (l *LoadData) Children() []sql.Node {
    65  	return nil
    66  }
    67  
    68  func (l *LoadData) IsReadOnly() bool {
    69  	return false
    70  }
    71  
    72  func (l *LoadData) SplitLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
    73  	// Return Nothing if at end of file and no data passed.
    74  	if atEOF && len(data) == 0 {
    75  		return 0, nil, nil
    76  	}
    77  
    78  	// Find the index of the LINES TERMINATED BY delim.
    79  	if i := strings.Index(string(data), l.LinesTerminatedBy); i >= 0 {
    80  		return i + len(l.LinesTerminatedBy), data[0:i], nil
    81  	}
    82  
    83  	// If at end of file with data return the data.
    84  	if atEOF {
    85  		return len(data), data, nil
    86  	}
    87  
    88  	return
    89  }
    90  
    91  func (l *LoadData) WithChildren(children ...sql.Node) (sql.Node, error) {
    92  	if len(children) != 0 {
    93  		return nil, sql.ErrInvalidChildrenNumber.New(l, len(children), 0)
    94  	}
    95  	nl := *l
    96  	return &nl, nil
    97  }
    98  
    99  // CheckPrivileges implements the interface sql.Node.
   100  func (l *LoadData) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool {
   101  	return opChecker.UserHasPrivileges(ctx, sql.NewPrivilegedOperation(sql.PrivilegeCheckSubject{}, sql.PrivilegeType_File))
   102  }
   103  
   104  // CollationCoercibility implements the interface sql.CollationCoercible.
   105  func (*LoadData) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   106  	return sql.Collation_binary, 7
   107  }
   108  
   109  func NewLoadData(local bool, file string, destSch sql.Schema, cols []string, ignoreNum int64, ignoreOrReplace string) *LoadData {
   110  	isReplace := ignoreOrReplace == sqlparser.ReplaceStr
   111  	isIgnore := ignoreOrReplace == sqlparser.IgnoreStr || (local && !isReplace)
   112  	return &LoadData{
   113  		Local:       local,
   114  		File:        file,
   115  		DestSch:     destSch,
   116  		ColumnNames: cols,
   117  		IgnoreNum:   ignoreNum,
   118  		IsIgnore:    isIgnore,
   119  		IsReplace:   isReplace,
   120  
   121  		FieldsTerminatedBy:  defaultFieldsTerminatedBy,
   122  		FieldsEnclosedBy:    defaultFieldsEnclosedBy,
   123  		FieldsEnclosedByOpt: defaultFieldsEnclosedByOpt,
   124  		FieldsEscapedBy:     defaultFieldsEscapedBy,
   125  
   126  		LinesStartingBy:   defaultLinesStartingBy,
   127  		LinesTerminatedBy: defaultLinesTerminatedBy,
   128  	}
   129  }