|
7 | 7 | "context" |
8 | 8 | "database/sql" |
9 | 9 | "encoding/hex" |
| 10 | + "fmt" |
10 | 11 | "math" |
11 | 12 | "reflect" |
12 | 13 | "strings" |
@@ -111,6 +112,72 @@ func TestBulkcopyWithInvalidNullableType(t *testing.T) { |
111 | 112 | } |
112 | 113 | } |
113 | 114 |
|
| 115 | +func TestBulkcopyColNameEscaping(t *testing.T) { |
| 116 | + tableName := "#table_test" |
| 117 | + columnName := `test_[]{}?@!#$%^&*()_+-=~'\";:/.,<>|\ ` |
| 118 | + |
| 119 | + pool, logger := open(t) |
| 120 | + defer pool.Close() |
| 121 | + defer logger.StopLogging() |
| 122 | + |
| 123 | + ctx, cancel := context.WithCancel(context.Background()) |
| 124 | + defer cancel() |
| 125 | + |
| 126 | + conn, err := pool.Conn(ctx) |
| 127 | + if err != nil { |
| 128 | + t.Fatal("failed to pull connection from pool", err) |
| 129 | + } |
| 130 | + defer conn.Close() |
| 131 | + |
| 132 | + q := TSQLQuoter{} |
| 133 | + tablesql := fmt.Sprintf(`CREATE TABLE %s (%s [int] NULL);`, tableName, q.ID(columnName)) |
| 134 | + _, err = conn.ExecContext(ctx, tablesql) |
| 135 | + if err != nil { |
| 136 | + t.Fatal("tablesql failed:", err) |
| 137 | + } |
| 138 | + |
| 139 | + stmt, err := conn.PrepareContext(ctx, CopyIn(tableName, BulkOptions{}, columnName)) |
| 140 | + if err != nil { |
| 141 | + t.Fatal(err) |
| 142 | + } |
| 143 | + defer stmt.Close() |
| 144 | + |
| 145 | + _, err = stmt.Exec(1) |
| 146 | + if err != nil { |
| 147 | + t.Fatal("AddRow failed: ", err.Error()) |
| 148 | + } |
| 149 | + |
| 150 | + result, err := stmt.Exec() |
| 151 | + if err != nil { |
| 152 | + t.Fatal("bulkcopy failed: ", err.Error()) |
| 153 | + } |
| 154 | + |
| 155 | + insertedRowCount, _ := result.RowsAffected() |
| 156 | + if insertedRowCount == 0 { |
| 157 | + t.Fatal("0 row inserted!") |
| 158 | + } |
| 159 | + |
| 160 | + //data verification |
| 161 | + rows, err := conn.QueryContext(ctx, "select "+q.ID(columnName)+" from "+tableName) |
| 162 | + if err != nil { |
| 163 | + t.Fatal(err) |
| 164 | + } |
| 165 | + defer rows.Close() |
| 166 | + |
| 167 | + for rows.Next() { |
| 168 | + var val int |
| 169 | + if err := rows.Scan(&val); err != nil { |
| 170 | + t.Fatal(err) |
| 171 | + } |
| 172 | + if val != 1 { |
| 173 | + t.Errorf("column %s : expected: 1, got: %d", columnName, val) |
| 174 | + } |
| 175 | + } |
| 176 | + if err := rows.Err(); err != nil { |
| 177 | + t.Error(err) |
| 178 | + } |
| 179 | +} |
| 180 | + |
114 | 181 | func testBulkcopy(t *testing.T, guidConversion bool) { |
115 | 182 | // TDS level Bulk Insert is not supported on Azure SQL Server. |
116 | 183 | if dsn := makeConnStrSettingGuidConversion(t, guidConversion); strings.HasSuffix(strings.Split(dsn.Host, ":")[0], ".database.windows.net") { |
|
0 commit comments