Skip to content

Commit ba2cb47

Browse files
committed
amend overflow fix
1 parent 32ba561 commit ba2cb47

File tree

12 files changed

+116
-351
lines changed

12 files changed

+116
-351
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
@@ -7,7 +7,6 @@ require (
77
github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71
88
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81
99
github.com/dolthub/vitess v0.0.0-20250730174048-497aebb8cea7
10-
github.com/go-kit/kit v0.10.0
1110
github.com/go-sql-driver/mysql v1.7.2-0.20231213112541-0004702b931d
1211
github.com/gocraft/dbr/v2 v2.7.2
1312
github.com/google/uuid v1.3.0
@@ -36,6 +35,7 @@ require (
3635
github.com/kr/text v0.2.0 // indirect
3736
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
3837
github.com/tetratelabs/wazero v1.8.2 // indirect
38+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
3939
golang.org/x/mod v0.12.0 // indirect
4040
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
4141
google.golang.org/protobuf v1.28.1 // indirect

go.sum

Lines changed: 0 additions & 331 deletions
Large diffs are not rendered by default.

server/handler.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"github.com/dolthub/vitess/go/sqltypes"
3333
querypb "github.com/dolthub/vitess/go/vt/proto/query"
3434
"github.com/dolthub/vitess/go/vt/sqlparser"
35-
"github.com/go-kit/kit/metrics/discard"
3635
"github.com/sirupsen/logrus"
3736
"go.opentelemetry.io/otel/attribute"
3837
otel "go.opentelemetry.io/otel/trace"
@@ -77,6 +76,10 @@ type Handler struct {
7776
maxLoggedQueryLen int
7877
encodeLoggedQuery bool
7978
sel ServerEventListener
79+
80+
queryCounter Counter
81+
queryErrorCounter Counter
82+
queryHistogram Histogram
8083
}
8184

8285
var _ mysql.Handler = (*Handler)(nil)
@@ -456,7 +459,7 @@ func (h *Handler) doQuery(
456459
}
457460
sqlCtx.GetLogger().WithField(sql.QueryTimeLogKey, time.Now()).Debugf("Starting query")
458461

459-
finish := observeQuery(sqlCtx, query)
462+
finish := h.observeQuery(sqlCtx, query)
460463
defer func() {
461464
finish(err)
462465
}()
@@ -1090,30 +1093,27 @@ func schemaToFields(ctx *sql.Context, s sql.Schema) []*querypb.Field {
10901093
return fields
10911094
}
10921095

1093-
var (
1094-
// QueryCounter describes a metric that accumulates number of queries monotonically.
1095-
QueryCounter = discard.NewCounter()
1096-
1097-
// QueryErrorCounter describes a metric that accumulates number of failed queries monotonically.
1098-
QueryErrorCounter = discard.NewCounter()
1099-
1100-
// QueryHistogram describes a queries latency.
1101-
QueryHistogram = discard.NewHistogram()
1102-
)
1103-
1104-
func observeQuery(ctx *sql.Context, query string) func(err error) {
1096+
func (h *Handler) observeQuery(ctx *sql.Context, query string) func(err error) {
11051097
span, ctx := ctx.Span("query", otel.WithAttributes(attribute.String("query", query)))
11061098

11071099
t := time.Now()
11081100
return func(err error) {
1101+
defer span.End()
1102+
11091103
if err != nil {
1110-
QueryErrorCounter.With("query", query, "error", err.Error()).Add(1)
1111-
} else {
1112-
QueryCounter.With("query", query).Add(1)
1113-
QueryHistogram.With("query", query, "duration", "seconds").Observe(time.Since(t).Seconds())
1104+
if h.queryErrorCounter != nil {
1105+
h.queryErrorCounter.With("query", query, "error", err.Error()).Add(1)
1106+
}
1107+
return
11141108
}
11151109

1116-
span.End()
1110+
if h.queryCounter != nil {
1111+
h.queryCounter.With("query", query).Add(1)
1112+
}
1113+
1114+
if h.queryHistogram != nil {
1115+
h.queryHistogram.With("query", query, "duration", "seconds").Observe(time.Since(t).Seconds())
1116+
}
11171117
}
11181118
}
11191119

server/metrics.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2025 Dolthub, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package server
16+
17+
// Counter describes a metric that accumulates values monotonically.
18+
// An example of a counter is the number of received HTTP requests.
19+
type Counter interface {
20+
With(labelValues ...string) Counter
21+
Add(delta float64)
22+
}
23+
24+
// Histogram describes a metric that takes repeated observations of the same
25+
// kind of thing, and produces a statistical summary of those observations,
26+
// typically expressed as quantiles or buckets. An example of a histogram is
27+
// HTTP request latencies.
28+
type Histogram interface {
29+
With(labelValues ...string) Histogram
30+
Observe(value float64)
31+
}

server/server.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ func NewServerWithHandler(
9898
maxLoggedQueryLen: cfg.MaxLoggedQueryLen,
9999
encodeLoggedQuery: cfg.EncodeLoggedQuery,
100100
sel: listener,
101+
102+
queryCounter: cfg.QueryCounter,
103+
queryErrorCounter: cfg.QueryErrorCounter,
104+
queryHistogram: cfg.QueryHistogram,
101105
}
102106

103107
handler, err := wrapper(h)

server/server_config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ type Config struct {
9494
// Used to get the ProtocolListener on server start.
9595
// If unset, defaults to MySQLProtocolListenerFactory.
9696
ProtocolListenerFactory ProtocolListenerFunc
97+
98+
// QueryCounter is a metrics.Counter that counts the number of queries executed.
99+
QueryCounter Counter
100+
// QueryErrorCounter is a metrics.Counter that counts the number of queries that resulted in an error.
101+
QueryErrorCounter Counter
102+
// QueryHistogram is a metrics.Histogram that measures the duration of queries executed.
103+
QueryHistogram Histogram
97104
}
98105

99106
func (c Config) NewConfig() (Config, error) {

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/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

0 commit comments

Comments
 (0)