Skip to content

Commit c450115

Browse files
committed
amend overflow fix
1 parent cf94656 commit c450115

File tree

10 files changed

+58
-18
lines changed

10 files changed

+58
-18
lines changed

enginetest/queries/script_queries.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,24 @@ type ScriptTestAssertion struct {
120120
// Unlike other engine tests, ScriptTests must be self-contained. No other tables are created outside the definition of
121121
// the tests.
122122
var ScriptTests = []ScriptTest{
123+
{
124+
// Regression test for https://github.com/dolthub/dolt/issues/9641
125+
Name: "bit union regression test dolt#9641",
126+
SetUpScript: []string{
127+
"CREATE TABLE bit_union_test_9641 (id INT PRIMARY KEY, flag BIT(1))",
128+
"INSERT INTO bit_union_test_9641 VALUES (1, 0), (2, 1)",
129+
},
130+
Assertions: []ScriptTestAssertion{
131+
{
132+
Query: "SELECT flag FROM bit_union_test_9641 WHERE id = 1 UNION SELECT NULL as flag",
133+
Expected: []sql.Row{{int64(0)}, {nil}},
134+
},
135+
{
136+
Query: "SELECT flag FROM bit_union_test_9641 WHERE id = 1 UNION SELECT 48 as flag",
137+
Expected: []sql.Row{{int64(0)}, {int64(48)}},
138+
},
139+
},
140+
},
123141
{
124142
Name: "outer join finish unmatched right side",
125143
SetUpScript: []string{

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/dolthub/go-icu-regex v0.0.0-20250327004329-6799764f2dad
77
github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71
88
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81
9-
github.com/dolthub/vitess v0.0.0-20250813175212-45844169a751
9+
github.com/dolthub/vitess v0.0.0-20250730174048-497aebb8cea7
1010
github.com/go-sql-driver/mysql v1.7.2-0.20231213112541-0004702b931d
1111
github.com/gocraft/dbr/v2 v2.7.2
1212
github.com/google/uuid v1.3.0

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9X
2020
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81/go.mod h1:siLfyv2c92W1eN/R4QqG/+RjjX5W2+gCTRjZxBjI3TY=
2121
github.com/dolthub/vitess v0.0.0-20250730174048-497aebb8cea7 h1:l+mWO0xoh4eG1J9gMS87opL6N6WGAQitF36R/Lg4bWs=
2222
github.com/dolthub/vitess v0.0.0-20250730174048-497aebb8cea7/go.mod h1:1gQZs/byeHLMSul3Lvl3MzioMtOW1je79QYGyi2fd70=
23-
github.com/dolthub/vitess v0.0.0-20250813175212-45844169a751 h1:BBQKyvyODewdQxS+ICklMn1d/fFj2pVlkmMN1QFY4ms=
24-
github.com/dolthub/vitess v0.0.0-20250813175212-45844169a751/go.mod h1:1gQZs/byeHLMSul3Lvl3MzioMtOW1je79QYGyi2fd70=
2523
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
2624
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
2725
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=

sql/analyzer/resolve_unions.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ func finalizeUnions(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope
9999
if err != nil {
100100
return nil, transform.SameTree, err
101101
}
102+
103+
// UNION operations can return multiple rows, so Max1Row optimization is invalid
104+
qFlags.Unset(sql.QFlagMax1Row)
105+
102106
return newN, transform.NewTree, nil
103107
})
104108
}

sql/expression/convert.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ func GetConvertToType(l, r sql.Type) string {
123123
if types.IsDecimal(l) || types.IsDecimal(r) {
124124
return ConvertToDecimal
125125
}
126+
if types.IsBit(l) || types.IsBit(r) {
127+
return ConvertToSigned
128+
}
126129
if types.IsUnsigned(l) && types.IsUnsigned(r) {
127130
return ConvertToUnsigned
128131
}

sql/iters/rel_iters.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,8 +601,9 @@ func (di *distinctIter) Dispose() {
601601
}
602602

603603
type UnionIter struct {
604-
Cur sql.RowIter
605-
NextIter func(ctx *sql.Context) (sql.RowIter, error)
604+
Cur sql.RowIter
605+
NextIter func(ctx *sql.Context) (sql.RowIter, error)
606+
ResultSchema sql.Schema
606607
}
607608

608609
func (ui *UnionIter) Next(ctx *sql.Context) (sql.Row, error) {
@@ -620,8 +621,23 @@ func (ui *UnionIter) Next(ctx *sql.Context) (sql.Row, error) {
620621
if err != nil {
621622
return nil, err
622623
}
623-
return ui.Cur.Next(ctx)
624+
res, err = ui.Cur.Next(ctx)
625+
if err != nil {
626+
return nil, err
627+
}
628+
}
629+
630+
// Convert BIT values to Int64 when schema generalization changed types for server engine compatibility
631+
if ui.ResultSchema != nil {
632+
for i, val := range res {
633+
if i < len(ui.ResultSchema) && val != nil {
634+
if converted, _, err := ui.ResultSchema[i].Type.Convert(ctx, val); err == nil {
635+
res[i] = converted
636+
}
637+
}
638+
}
624639
}
640+
625641
return res, err
626642
}
627643

sql/plan/set_op.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"strings"
2020

2121
"github.com/dolthub/go-mysql-server/sql"
22+
"github.com/dolthub/go-mysql-server/sql/types"
2223
)
2324

2425
const (
@@ -100,6 +101,7 @@ func (s *SetOp) Schema() sql.Schema {
100101
for i := range ls {
101102
c := *ls[i]
102103
if i < len(rs) {
104+
c.Type = types.GeneralizeTypes(ls[i].Type, rs[i].Type)
103105
c.Nullable = ls[i].Nullable || rs[i].Nullable
104106
}
105107
ret[i] = &c

sql/rowexec/rel.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ func (b *BaseBuilder) buildSetOp(ctx *sql.Context, s *plan.SetOp, row sql.Row) (
813813
NextIter: func(ctx *sql.Context) (sql.RowIter, error) {
814814
return b.buildNodeExec(ctx, s.Right(), row)
815815
},
816+
ResultSchema: s.Schema(),
816817
}
817818
case plan.IntersectType:
818819
var iter2 sql.RowIter

sql/types/bit.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ func (t BitType_) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes.Va
193193
if v == nil {
194194
return sqltypes.NULL, nil
195195
}
196+
197+
// Delegate int64 values to Int64.SQL to prevent server engine []uint8 serialization errors
198+
if int64Val, ok := v.(int64); ok {
199+
return Int64.SQL(ctx, dest, int64Val)
200+
}
196201
value, _, err := t.Convert(ctx, v)
197202
if err != nil {
198203
return sqltypes.Value{}, err

sql/types/conversion.go

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,11 @@ func generalizeNumberTypes(a, b sql.Type) sql.Type {
637637
// TODO: Create and handle "Illegal mix of collations" error
638638
// TODO: Handle extended types, like DoltgresType
639639
func GeneralizeTypes(a, b sql.Type) sql.Type {
640+
// BIT types must convert to Int64 in UNION to avoid server engine serialization errors with []uint8
641+
if (IsBit(a) || IsBit(b)) && (IsBit(a) && IsBit(b) || IsNullType(a) || IsNullType(b)) {
642+
return Int64
643+
}
644+
640645
if reflect.DeepEqual(a, b) {
641646
return a
642647
}
@@ -693,18 +698,6 @@ func GeneralizeTypes(a, b sql.Type) sql.Type {
693698
return LongBlob
694699
}
695700

696-
aIsBit := IsBit(a)
697-
bIsBit := IsBit(b)
698-
if aIsBit && bIsBit {
699-
// TODO: match max bits to max of max bits between a and b
700-
return a.Promote()
701-
}
702-
if aIsBit {
703-
a = Int64
704-
}
705-
if bIsBit {
706-
b = Int64
707-
}
708701

709702
aIsYear := IsYear(a)
710703
bIsYear := IsYear(b)

0 commit comments

Comments
 (0)