From 9e4dbea26567a388e7672b5d98ee53f2054e4d56 Mon Sep 17 00:00:00 2001 From: James Cor Date: Wed, 6 Aug 2025 16:39:11 -0700 Subject: [PATCH 1/6] replace append with cast --- sql/types/decimal.go | 3 ++- sql/types/json.go | 3 ++- sql/types/system_enum.go | 3 ++- sql/types/system_set.go | 3 ++- sql/types/system_string.go | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sql/types/decimal.go b/sql/types/decimal.go index ed69509184..45cd0043cb 100644 --- a/sql/types/decimal.go +++ b/sql/types/decimal.go @@ -303,7 +303,8 @@ func (t DecimalType_) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltype if err != nil { return sqltypes.Value{}, err } - val := AppendAndSliceString(dest, t.DecimalValueStringFixed(value.Decimal)) + //val := AppendAndSliceString(dest, t.DecimalValueStringFixed(value.Decimal)) + val := []byte(t.DecimalValueStringFixed(value.Decimal)) return sqltypes.MakeTrusted(sqltypes.Decimal, val), nil } diff --git a/sql/types/json.go b/sql/types/json.go index 44cb3434f9..4ced0ed009 100644 --- a/sql/types/json.go +++ b/sql/types/json.go @@ -154,7 +154,8 @@ func (t JsonType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes.Va if err != nil { return sqltypes.NULL, err } - val = AppendAndSliceString(dest, str) + //val = AppendAndSliceString(dest, str) + val = []byte(str) } return sqltypes.MakeTrusted(sqltypes.TypeJSON, val), nil diff --git a/sql/types/system_enum.go b/sql/types/system_enum.go index c6b85b57f9..02d7993990 100644 --- a/sql/types/system_enum.go +++ b/sql/types/system_enum.go @@ -157,7 +157,8 @@ func (t systemEnumType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqlty return sqltypes.Value{}, err } - val := AppendAndSliceString(dest, v.(string)) + //val := AppendAndSliceString(dest, v.(string)) + val := []byte(v.(string)) return sqltypes.MakeTrusted(t.Type(), val), nil } diff --git a/sql/types/system_set.go b/sql/types/system_set.go index fd1e0fabee..8a42675047 100644 --- a/sql/types/system_set.go +++ b/sql/types/system_set.go @@ -143,7 +143,8 @@ func (t systemSetType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltyp return sqltypes.Value{}, err } - val := AppendAndSliceString(dest, value) + //val := AppendAndSliceString(dest, value) + val := []byte(value) return sqltypes.MakeTrusted(t.Type(), val), nil } diff --git a/sql/types/system_string.go b/sql/types/system_string.go index 07459cb26e..f848690c75 100644 --- a/sql/types/system_string.go +++ b/sql/types/system_string.go @@ -102,7 +102,8 @@ func (t systemStringType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sql return sqltypes.Value{}, err } - val := AppendAndSliceString(dest, v.(string)) + //val := AppendAndSliceString(dest, v.(string)) + val := []byte(v.(string)) return sqltypes.MakeTrusted(t.Type(), val), nil } From cfc8eb37d52f797064f19b3a5ad072836a90dc08 Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 7 Aug 2025 10:22:23 -0700 Subject: [PATCH 2/6] revert and try make --- sql/types/decimal.go | 3 +-- sql/types/json.go | 3 +-- sql/types/strings.go | 14 +++++--------- sql/types/system_enum.go | 3 +-- sql/types/system_set.go | 3 +-- sql/types/system_string.go | 3 +-- 6 files changed, 10 insertions(+), 19 deletions(-) diff --git a/sql/types/decimal.go b/sql/types/decimal.go index 45cd0043cb..ed69509184 100644 --- a/sql/types/decimal.go +++ b/sql/types/decimal.go @@ -303,8 +303,7 @@ func (t DecimalType_) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltype if err != nil { return sqltypes.Value{}, err } - //val := AppendAndSliceString(dest, t.DecimalValueStringFixed(value.Decimal)) - val := []byte(t.DecimalValueStringFixed(value.Decimal)) + val := AppendAndSliceString(dest, t.DecimalValueStringFixed(value.Decimal)) return sqltypes.MakeTrusted(sqltypes.Decimal, val), nil } diff --git a/sql/types/json.go b/sql/types/json.go index 4ced0ed009..44cb3434f9 100644 --- a/sql/types/json.go +++ b/sql/types/json.go @@ -154,8 +154,7 @@ func (t JsonType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes.Va if err != nil { return sqltypes.NULL, err } - //val = AppendAndSliceString(dest, str) - val = []byte(str) + val = AppendAndSliceString(dest, str) } return sqltypes.MakeTrusted(sqltypes.TypeJSON, val), nil diff --git a/sql/types/strings.go b/sql/types/strings.go index 96fadd5498..e817f569f8 100644 --- a/sql/types/strings.go +++ b/sql/types/strings.go @@ -480,7 +480,7 @@ func ConvertToBytes(ctx context.Context, v interface{}, t sql.StringType, dest [ val = append(dest, b...) start = len(dest) } - val = append(val, bytes.Repeat([]byte{0}, int(st.maxCharLength)-len(val))...) + val = append(val, make([]byte, int(st.maxCharLength)-len(val))...) } } val = val[start:] @@ -715,10 +715,13 @@ func (t StringType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes. var valueBytes []byte switch v := v.(type) { case JSONBytes: - valueBytes, err = v.GetBytes(ctx) + // TODO: put on dest? + val, err = v.GetBytes(ctx) if err != nil { return sqltypes.Value{}, err } + dest = append(dest, val...) + valueBytes = dest[start:] case []byte: valueBytes = v case string: @@ -893,10 +896,3 @@ func AppendAndSliceString(buffer []byte, addition string) (slice []byte) { slice = buffer[stop:] return } - -func AppendAndSliceBytes(buffer, addition []byte) (slice []byte) { - stop := len(buffer) - buffer = append(buffer, addition...) - slice = buffer[stop:] - return -} diff --git a/sql/types/system_enum.go b/sql/types/system_enum.go index 02d7993990..c6b85b57f9 100644 --- a/sql/types/system_enum.go +++ b/sql/types/system_enum.go @@ -157,8 +157,7 @@ func (t systemEnumType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqlty return sqltypes.Value{}, err } - //val := AppendAndSliceString(dest, v.(string)) - val := []byte(v.(string)) + val := AppendAndSliceString(dest, v.(string)) return sqltypes.MakeTrusted(t.Type(), val), nil } diff --git a/sql/types/system_set.go b/sql/types/system_set.go index 8a42675047..fd1e0fabee 100644 --- a/sql/types/system_set.go +++ b/sql/types/system_set.go @@ -143,8 +143,7 @@ func (t systemSetType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltyp return sqltypes.Value{}, err } - //val := AppendAndSliceString(dest, value) - val := []byte(value) + val := AppendAndSliceString(dest, value) return sqltypes.MakeTrusted(t.Type(), val), nil } diff --git a/sql/types/system_string.go b/sql/types/system_string.go index f848690c75..07459cb26e 100644 --- a/sql/types/system_string.go +++ b/sql/types/system_string.go @@ -102,8 +102,7 @@ func (t systemStringType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sql return sqltypes.Value{}, err } - //val := AppendAndSliceString(dest, v.(string)) - val := []byte(v.(string)) + val := AppendAndSliceString(dest, v.(string)) return sqltypes.MakeTrusted(t.Type(), val), nil } From b7ae058b985ec46dbad6157eee7e14bc68a18710 Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 7 Aug 2025 10:25:59 -0700 Subject: [PATCH 3/6] missed one --- sql/types/strings.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sql/types/strings.go b/sql/types/strings.go index e817f569f8..17eeaef901 100644 --- a/sql/types/strings.go +++ b/sql/types/strings.go @@ -15,7 +15,6 @@ package types import ( - "bytes" "context" "fmt" "reflect" @@ -715,13 +714,10 @@ func (t StringType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes. var valueBytes []byte switch v := v.(type) { case JSONBytes: - // TODO: put on dest? - val, err = v.GetBytes(ctx) + valueBytes, err = v.GetBytes(ctx) if err != nil { return sqltypes.Value{}, err } - dest = append(dest, val...) - valueBytes = dest[start:] case []byte: valueBytes = v case string: @@ -760,7 +756,7 @@ func (t StringType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes. valueBytes, err = ConvertToBytes(ctx, v, t, dest) } if t.baseType == sqltypes.Binary { - val = append(val, bytes.Repeat([]byte{0}, int(t.maxCharLength)-len(val))...) + val = append(val, make([]byte, int(t.maxCharLength)-len(val))...) } // Note: MySQL does not validate charset when returning query results. // It returns whatever data is stored, allowing users to query and clean up @@ -780,7 +776,6 @@ func (t StringType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes. snippetStr := strings2.ToValidUTF8(string(snippet), string(utf8.RuneError)) return sqltypes.Value{}, sql.ErrCharSetFailedToEncode.New(resultCharset.Name(), utf8.ValidString(snippetStr), snippet) } - //val = AppendAndSliceBytes(dest, encodedBytes) val = encodedBytes } From 5e517250039ddf5d7cafefe9e6319714944761fa Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 7 Aug 2025 13:23:36 -0700 Subject: [PATCH 4/6] reduce row allocations --- sql/rowexec/agg.go | 18 ++++++++++-------- sql/rowexec/ddl_iters.go | 2 +- sql/rowexec/rel.go | 8 +++----- sql/types/number.go | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sql/rowexec/agg.go b/sql/rowexec/agg.go index 384e8efe91..a80b30f5e9 100644 --- a/sql/rowexec/agg.go +++ b/sql/rowexec/agg.go @@ -117,6 +117,8 @@ type groupByGroupingIter struct { pos int child sql.RowIter dispose sql.DisposeFunc + keyRow sql.Row + keySch sql.Schema } func newGroupByGroupingIter( @@ -128,6 +130,8 @@ func newGroupByGroupingIter( selectedExprs: selectedExprs, groupByExprs: groupByExprs, child: child, + keyRow: make(sql.Row, len(groupByExprs)), + keySch: make(sql.Schema, len(groupByExprs)), } } @@ -167,7 +171,7 @@ func (i *groupByGroupingIter) compute(ctx *sql.Context) error { return err } - key, err := groupingKey(ctx, i.groupByExprs, row) + key, err := i.groupingKey(ctx, i.groupByExprs, row) if err != nil { return err } @@ -237,10 +241,8 @@ func (i *groupByGroupingIter) Dispose() { } } -func groupingKey(ctx *sql.Context, exprs []sql.Expression, row sql.Row) (uint64, error) { - var keyRow = make(sql.Row, len(exprs)) - var keySch = make(sql.Schema, len(exprs)) - for i, expr := range exprs { +func (i *groupByGroupingIter) groupingKey(ctx *sql.Context, exprs []sql.Expression, row sql.Row) (uint64, error) { + for idx, expr := range exprs { v, err := expr.Eval(ctx, row) if err != nil { return 0, err @@ -256,10 +258,10 @@ func groupingKey(ctx *sql.Context, exprs []sql.Expression, row sql.Row) (uint64, v = string(val) } - keyRow[i] = v - keySch[i] = &sql.Column{Type: typ} + i.keyRow[idx] = v + i.keySch[idx] = &sql.Column{Type: typ} } - return hash.HashOf(ctx, keySch, keyRow) + return hash.HashOf(ctx, i.keySch, i.keyRow) } func newAggregationBuffer(expr sql.Expression) (sql.AggregationBuffer, error) { diff --git a/sql/rowexec/ddl_iters.go b/sql/rowexec/ddl_iters.go index bf8a0b5797..1dc4f9460d 100644 --- a/sql/rowexec/ddl_iters.go +++ b/sql/rowexec/ddl_iters.go @@ -109,7 +109,7 @@ func (l *loadDataIter) Next(ctx *sql.Context) (returnRow sql.Row, returnErr erro } } - return sql.NewRow(row...), nil + return row, nil } func (l *loadDataIter) Close(ctx *sql.Context) error { diff --git a/sql/rowexec/rel.go b/sql/rowexec/rel.go index 391a9a61e1..8cc491428f 100644 --- a/sql/rowexec/rel.go +++ b/sql/rowexec/rel.go @@ -55,7 +55,7 @@ func (b *BaseBuilder) buildTopN(ctx *sql.Context, n *plan.TopN, row sql.Row) (sq func (b *BaseBuilder) buildValueDerivedTable(ctx *sql.Context, n *plan.ValueDerivedTable, row sql.Row) (sql.RowIter, error) { rows := make([]sql.Row, len(n.ExpressionTuples)) for i, et := range n.ExpressionTuples { - vals := make([]interface{}, len(et)) + rows[i] = make(sql.Row, len(et)) for j, e := range et { var err error p, err := e.Eval(ctx, row) @@ -63,17 +63,15 @@ func (b *BaseBuilder) buildValueDerivedTable(ctx *sql.Context, n *plan.ValueDeri return nil, err } // cast all row values to the most permissive type - vals[j], _, err = n.Schema()[j].Type.Convert(ctx, p) + rows[i][j], _, err = n.Schema()[j].Type.Convert(ctx, p) if err != nil { return nil, err } // decimalType.Convert() does not use the given type precision and scale information if t, ok := n.Schema()[j].Type.(sql.DecimalType); ok { - vals[j] = vals[j].(decimal.Decimal).Round(int32(t.Scale())) + rows[i][j] = rows[i][j].(decimal.Decimal).Round(int32(t.Scale())) } } - - rows[i] = sql.NewRow(vals...) } return sql.RowsToRowIter(rows...), nil diff --git a/sql/types/number.go b/sql/types/number.go index af0d6a498f..20bbd1d961 100644 --- a/sql/types/number.go +++ b/sql/types/number.go @@ -601,7 +601,7 @@ func (t NumberTypeImpl_) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqlt case []byte: dest = str case string: - dest = []byte(str) + dest = append(dest, str...) default: return sqltypes.Value{}, err } From 9d5ded5af4f5505ab5975c320321d36c1eebe940 Mon Sep 17 00:00:00 2001 From: James Cor Date: Fri, 8 Aug 2025 11:04:05 -0700 Subject: [PATCH 5/6] clean up --- sql/rowexec/rel.go | 7 ++++--- sql/types/number.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sql/rowexec/rel.go b/sql/rowexec/rel.go index 8cc491428f..42942213f9 100644 --- a/sql/rowexec/rel.go +++ b/sql/rowexec/rel.go @@ -55,7 +55,7 @@ func (b *BaseBuilder) buildTopN(ctx *sql.Context, n *plan.TopN, row sql.Row) (sq func (b *BaseBuilder) buildValueDerivedTable(ctx *sql.Context, n *plan.ValueDerivedTable, row sql.Row) (sql.RowIter, error) { rows := make([]sql.Row, len(n.ExpressionTuples)) for i, et := range n.ExpressionTuples { - rows[i] = make(sql.Row, len(et)) + vals := make(sql.Row, len(et)) for j, e := range et { var err error p, err := e.Eval(ctx, row) @@ -63,15 +63,16 @@ func (b *BaseBuilder) buildValueDerivedTable(ctx *sql.Context, n *plan.ValueDeri return nil, err } // cast all row values to the most permissive type - rows[i][j], _, err = n.Schema()[j].Type.Convert(ctx, p) + vals[j], _, err = n.Schema()[j].Type.Convert(ctx, p) if err != nil { return nil, err } // decimalType.Convert() does not use the given type precision and scale information if t, ok := n.Schema()[j].Type.(sql.DecimalType); ok { - rows[i][j] = rows[i][j].(decimal.Decimal).Round(int32(t.Scale())) + vals[j] = vals[j].(decimal.Decimal).Round(int32(t.Scale())) } } + rows[i] = vals } return sql.RowsToRowIter(rows...), nil diff --git a/sql/types/number.go b/sql/types/number.go index 20bbd1d961..9681949abd 100644 --- a/sql/types/number.go +++ b/sql/types/number.go @@ -931,7 +931,7 @@ func (t NumberTypeImpl_) IsSigned() bool { return false } -// DisplayWidth() implements NumberType inteface. +// DisplayWidth implements NumberType interface. func (t NumberTypeImpl_) DisplayWidth() int { return t.displayWidth } From 6c83e6d50f70409e7a84f3b2a05b3ab8a5a72837 Mon Sep 17 00:00:00 2001 From: James Cor Date: Sun, 10 Aug 2025 22:53:25 -0700 Subject: [PATCH 6/6] comment --- sql/rowexec/agg.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/rowexec/agg.go b/sql/rowexec/agg.go index a80b30f5e9..a24cecb7a6 100644 --- a/sql/rowexec/agg.go +++ b/sql/rowexec/agg.go @@ -117,8 +117,10 @@ type groupByGroupingIter struct { pos int child sql.RowIter dispose sql.DisposeFunc - keyRow sql.Row - keySch sql.Schema + + // buffers to reduce slice allocations + keyRow sql.Row + keySch sql.Schema } func newGroupByGroupingIter(