(ctx *sql.Context, insert *plan.InsertInto, dst sql.InsertableTable, load *plan.LoadData, filePath string)
| 113 | } |
| 114 | |
| 115 | func (db *DuckBuilder) executeLoadData(ctx *sql.Context, insert *plan.InsertInto, dst sql.InsertableTable, load *plan.LoadData, filePath string) (sql.RowIter, error) { |
| 116 | // Build the DuckDB INSERT INTO statement. |
| 117 | var b strings.Builder |
| 118 | b.Grow(256) |
| 119 | |
| 120 | keyless := sql.IsKeyless(dst.Schema()) |
| 121 | // TODO(fan): This is an ugly hack for MySQL Shell's utilities to work properly. |
| 122 | if !keyless { |
| 123 | if t, ok := dst.(*catalog.Table); ok { |
| 124 | // Replicated tables do not have physical primary keys. |
| 125 | // Their logical primary keys are fake and should not be used in INSERT INTO statements. |
| 126 | // https://github.com/apecloud/myduckserver/issues/272 |
| 127 | keyless = t.ExtraTableInfo().Replicated || !t.HasPrimaryKey() |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | b.WriteString("INSERT") |
| 132 | if load.IsIgnore && !keyless { |
| 133 | b.WriteString(" OR IGNORE") |
| 134 | } else if load.IsReplace && !keyless { |
| 135 | b.WriteString(" OR REPLACE") |
| 136 | } |
| 137 | b.WriteString(" INTO ") |
| 138 | |
| 139 | qualifiedTableName := catalog.ConnectIdentifiersANSI(insert.Database().Name(), dst.Name()) |
| 140 | b.WriteString(qualifiedTableName) |
| 141 | |
| 142 | if len(load.ColNames) > 0 { |
| 143 | b.WriteString(" (") |
| 144 | b.WriteString(catalog.QuoteIdentifierANSI(load.ColNames[0])) |
| 145 | for _, col := range load.ColNames[1:] { |
| 146 | b.WriteString(", ") |
| 147 | b.WriteString(catalog.QuoteIdentifierANSI(col)) |
| 148 | } |
| 149 | b.WriteString(")") |
| 150 | } |
| 151 | |
| 152 | b.WriteString(" FROM ") |
| 153 | b.WriteString("read_csv('") |
| 154 | b.WriteString(filePath) |
| 155 | b.WriteString("'") |
| 156 | |
| 157 | b.WriteString(", auto_detect = false") |
| 158 | b.WriteString(", header = false") |
| 159 | b.WriteString(", null_padding = true") |
| 160 | |
| 161 | b.WriteString(", new_line = ") |
| 162 | if len(load.LinesTerminatedBy) == 1 { |
| 163 | b.WriteString(singleQuotedDuckChar(load.LinesTerminatedBy)) |
| 164 | } else { |
| 165 | b.WriteString(`'\r\n'`) |
| 166 | } |
| 167 | |
| 168 | b.WriteString(", sep = ") |
| 169 | b.WriteString(singleQuotedDuckChar(load.FieldsTerminatedBy)) |
| 170 | |
| 171 | b.WriteString(", quote = ") |
| 172 | b.WriteString(singleQuotedDuckChar(load.FieldsEnclosedBy)) |
no test coverage detected