func newImport(db *sql.DB, schema string, tableName string, columns []string) (*Import, error) { txn, err := db.Begin() if err != nil { return nil, err } stmt, err := txn.Prepare(pq.CopyInSchema(schema, tableName, columns...)) if err != nil { return nil, err } return &Import{txn, stmt}, nil }
// TestCopyRandom inserts 100 random rows using COPY and ensures the SELECT'd // data is the same. func TestCopyRandom(t *testing.T) { defer leaktest.AfterTest(t)() params, _ := createTestServerParams() s, db, _ := serverutils.StartServer(t, params) defer s.Stopper().Stop() if _, err := db.Exec(` CREATE DATABASE d; CREATE TABLE IF NOT EXISTS d.t ( id INT PRIMARY KEY, n INTERVAL, o BOOL, i INT, f FLOAT, e DECIMAL, t TIMESTAMP, s STRING, b BYTES, tz TIMESTAMP WITH TIME ZONE ); `); err != nil { t.Fatal(err) } txn, err := db.Begin() if err != nil { t.Fatal(err) } stmt, err := txn.Prepare(pq.CopyInSchema("d", "t", "id", "n", "o", "i", "f", "e", "t", "s", "b", "tz")) if err != nil { t.Fatal(err) } rng := rand.New(rand.NewSource(0)) types := []sqlbase.ColumnType_Kind{ sqlbase.ColumnType_BOOL, sqlbase.ColumnType_INT, sqlbase.ColumnType_FLOAT, sqlbase.ColumnType_DECIMAL, sqlbase.ColumnType_TIMESTAMP, sqlbase.ColumnType_STRING, sqlbase.ColumnType_BYTES, sqlbase.ColumnType_TIMESTAMPTZ, } var inputs [][]interface{} for i := 0; i < 100; i++ { row := make([]interface{}, len(types)+2) row[0] = strconv.Itoa(i) row[1] = time.Duration(rng.Int63()).String() for j, t := range types { d := sqlbase.RandDatum(rng, sqlbase.ColumnType{Kind: t}, false) ds := parser.AsStringWithFlags(d, parser.FmtBareStrings) switch t { case sqlbase.ColumnType_DECIMAL: // Trailing 0s aren't represented below, so truncate here. ds = strings.TrimRight(ds, "0") } row[j+2] = ds } _, err = stmt.Exec(row...) if err != nil { t.Fatal(err) } inputs = append(inputs, row) } err = stmt.Close() if err != nil { t.Fatal(err) } err = txn.Commit() if err != nil { t.Fatal(err) } rows, err := db.Query("SELECT * FROM d.t ORDER BY id") if err != nil { t.Fatal(err) } for row, in := range inputs { if !rows.Next() { t.Fatal("expected more results") } data := make([]interface{}, len(in)) for i := range data { data[i] = new(interface{}) } if err := rows.Scan(data...); err != nil { t.Fatal(err) } for i, d := range data { v := d.(*interface{}) d := *v ds := fmt.Sprint(d) switch d := d.(type) { case []byte: ds = string(d) case time.Time: dt := parser.MakeDTimestamp(d, time.Microsecond) ds = parser.AsStringWithFlags(dt, parser.FmtBareStrings) } if !reflect.DeepEqual(in[i], ds) { t.Fatalf("row %v, col %v: got %#v (%T), expected %#v", row, i, ds, d, in[i]) } } } }