diff --git a/go/libraries/doltcore/table/untyped/csv/writer.go b/go/libraries/doltcore/table/untyped/csv/writer.go index 8fd56e19f57..0781d6608fd 100644 --- a/go/libraries/doltcore/table/untyped/csv/writer.go +++ b/go/libraries/doltcore/table/untyped/csv/writer.go @@ -126,19 +126,17 @@ func (csvw *CSVWriter) WriteSqlRow(ctx *sql.Context, r sql.Row) error { } func toCsvString(ctx *sql.Context, colType sql.Type, val interface{}) (string, error) { - var v string - // Due to BIT's unique output, we special-case writing the integer specifically for CSV + // For BIT, emit base-10 int, instead of bytes if _, ok := colType.(types.BitType); ok { - v = strconv.FormatUint(val.(uint64), 10) - } else { - var err error - v, err = sqlutil.SqlColToStr(ctx, colType, val) + // Normalize to handle UNION type generalization (e.g., int64 -> uint64) + norm, _, err := colType.Convert(ctx, val) if err != nil { return "", err } + return strconv.FormatUint(norm.(uint64), 10), nil } - return v, nil + return sqlutil.SqlColToStr(ctx, colType, val) } func (csvw *CSVWriter) processRowWithSchema(r sql.Row, ctx *sql.Context) ([]*string, error) { diff --git a/integration-tests/bats/sql-export.bats b/integration-tests/bats/sql-export.bats index 2061e74642e..001cdd89196 100644 --- a/integration-tests/bats/sql-export.bats +++ b/integration-tests/bats/sql-export.bats @@ -101,3 +101,11 @@ teardown() { [ "$status" -eq 1 ] [[ "$output" =~ "Result consisted of more than one row" ]] || false } + +@test "sql-export: bit union csv output regression test for dolt#9641" { + dolt sql -q "CREATE TABLE collection (id INT, archived BIT(1));" + dolt sql -q "INSERT INTO collection VALUES (1, b'0'), (2, b'0');" + run dolt sql --result-format=csv -q "SELECT * FROM (SELECT archived FROM collection WHERE archived = FALSE UNION ALL SELECT NULL AS archived FROM collection WHERE id = 1) AS dummy_alias;" + [ "$status" -eq 0 ] + [[ "$output" =~ "archived" ]] || false +}