| 3308 | break |
| 3309 | } |
| 3310 | } |
| 3311 | } |
| 3312 | default: |
| 3313 | t.Errorf("unhandled type in test: %T", expected) |
| 3314 | } |
| 3315 | }) |
| 3316 | } |
| 3317 | } |
| 3318 | |
| 3319 | func TestDecodeBinaryCopy_FloatWidthMismatch(t *testing.T) { |
| 3320 | // DuckDB's postgres extension may send float data with mismatched width |
| 3321 | // e.g., float4 OID but 8-byte data, or float8 OID but 4-byte data |
| 3322 | |
| 3323 | // float4 OID with 8-byte data should decode as float8 |
| 3324 | float8Data := make([]byte, 8) |
| 3325 | bits := math.Float64bits(3.14) |
| 3326 | binary.BigEndian.PutUint64(float8Data, bits) |
| 3327 | |
| 3328 | result, err := decodeBinaryCopy(float8Data, OidFloat4) |
| 3329 | if err != nil { |
| 3330 | t.Fatalf("decodeBinaryCopy(float8 data, OidFloat4) error: %v", err) |
| 3331 | } |
| 3332 | if v, ok := result.(float64); !ok || math.Abs(v-3.14) > 0.001 { |
| 3333 | t.Errorf("got %v (%T), want ~3.14", result, result) |
| 3334 | } |
| 3335 | |
| 3336 | // float8 OID with 4-byte data should decode as float4 |
| 3337 | float4Data := make([]byte, 4) |
| 3338 | bits32 := math.Float32bits(2.5) |
| 3339 | binary.BigEndian.PutUint32(float4Data, bits32) |
| 3340 | |
| 3341 | result, err = decodeBinaryCopy(float4Data, OidFloat8) |
| 3342 | if err != nil { |
| 3343 | t.Fatalf("decodeBinaryCopy(float4 data, OidFloat8) error: %v", err) |
| 3344 | } |
| 3345 | if v, ok := result.(float32); !ok || math.Abs(float64(v)-2.5) > 0.001 { |
| 3346 | t.Errorf("got %v (%T), want ~2.5", result, result) |
| 3347 | } |
| 3348 | } |
| 3349 | |
| 3350 | func TestParseMultiLineCSV(t *testing.T) { |
| 3351 | // This tests the fix for COPY FROM STDIN with multi-line quoted fields. |
| 3352 | // Previously, we split by newlines first then parsed each line, which broke |
| 3353 | // when quoted fields contained embedded newlines (e.g., JSON with formatting). |
| 3354 | // Now we use csv.Reader on the entire buffer which handles this correctly. |
| 3355 | |
| 3356 | tests := []struct { |
| 3357 | name string |
| 3358 | input string |
| 3359 | delimiter string |
| 3360 | expected [][]string |
| 3361 | }{ |
| 3362 | { |
| 3363 | name: "simple rows no newlines", |
| 3364 | input: "a,b,c\n1,2,3\n", |
| 3365 | delimiter: ",", |
| 3366 | expected: [][]string{{"a", "b", "c"}, {"1", "2", "3"}}, |
| 3367 | }, |