Skip to content

Commit 6a1307e

Browse files
committed
fix merge conflict
2 parents da4365d + 7662160 commit 6a1307e

File tree

8 files changed

+282
-10
lines changed

8 files changed

+282
-10
lines changed

enginetest/queries/script_queries.go

Lines changed: 162 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,7 @@ CREATE TABLE tab3 (
16751675
"INSERT INTO tab2 VALUES (1, 'b'), (2, 'm'), (3, 'g')",
16761676
"SELECT m.id, t.s FROM tab1 m JOIN tab2 t on m.id = t.i2 ORDER BY t.s DESC LIMIT 1 INTO @myId, @myText",
16771677
// TODO: union statement does not handle order by and limit clauses
1678-
//"SELECT id FROM tab1 UNION select s FROM tab2 LIMIT 1 INTO @myUnion",
1678+
// "SELECT id FROM tab1 UNION select s FROM tab2 LIMIT 1 INTO @myUnion",
16791679
"SELECT id FROM tab1 WHERE id > 3 UNION select s FROM tab2 WHERE s < 'f' INTO @mustSingleVar",
16801680
},
16811681
Assertions: []ScriptTestAssertion{
@@ -2760,6 +2760,163 @@ CREATE TABLE tab3 (
27602760
},
27612761
},
27622762
},
2763+
{
2764+
Name: "Group Concat with Subquery in ORDER BY",
2765+
Dialect: "mysql",
2766+
SetUpScript: []string{
2767+
"CREATE TABLE test_data (id INT PRIMARY KEY, name VARCHAR(50), age INT, category VARCHAR(10))",
2768+
`INSERT INTO test_data VALUES
2769+
(1, 'Alice', 25, 'A'),
2770+
(2, 'Bob', 30, 'B'),
2771+
(3, 'Charlie', 22, 'A'),
2772+
(4, 'Diana', 28, 'C'),
2773+
(5, 'Eve', 35, 'B'),
2774+
(6, 'Frank', 26, 'A')`,
2775+
},
2776+
Assertions: []ScriptTestAssertion{
2777+
{
2778+
Skip: true,
2779+
Query: "SELECT category, group_concat(name ORDER BY (SELECT COUNT(*) FROM test_data t2 WHERE t2.category = test_data.category AND t2.age < test_data.age)) FROM test_data GROUP BY category ORDER BY category",
2780+
Expected: []sql.Row{{"A", "Charlie,Alice,Frank"}, {"B", "Bob,Eve"}, {"C", "Diana"}},
2781+
},
2782+
{
2783+
Skip: true,
2784+
Query: "SELECT group_concat(name ORDER BY (SELECT AVG(age) FROM test_data t2 WHERE t2.category = test_data.category), id) FROM test_data;",
2785+
Expected: []sql.Row{{"Alice,Charlie,Frank,Diana,Bob,Eve"}},
2786+
},
2787+
{
2788+
Query: "SELECT category, group_concat(name ORDER BY (SELECT MAX(age) FROM test_data t2 WHERE t2.id <= test_data.id)) FROM test_data GROUP BY category ORDER BY category",
2789+
Expected: []sql.Row{{"A", "Alice,Charlie,Frank"}, {"B", "Bob,Eve"}, {"C", "Diana"}},
2790+
},
2791+
},
2792+
},
2793+
{
2794+
Name: "Group Concat with Subquery in ORDER BY - Additional Edge Cases",
2795+
Dialect: "mysql",
2796+
SetUpScript: []string{
2797+
"CREATE TABLE products (id INT PRIMARY KEY, name VARCHAR(50), price DECIMAL(10,2), category_id INT, supplier_id INT)",
2798+
"CREATE TABLE categories (id INT PRIMARY KEY, name VARCHAR(50), priority INT)",
2799+
"CREATE TABLE suppliers (id INT PRIMARY KEY, name VARCHAR(50), rating INT)",
2800+
"INSERT INTO products VALUES (1, 'Laptop', 999.99, 1, 1), (2, 'Mouse', 25.50, 1, 2), (3, 'Keyboard', 75.00, 1, 1)",
2801+
"INSERT INTO products VALUES (4, 'Chair', 150.00, 2, 3), (5, 'Desk', 300.00, 2, 3), (6, 'Monitor', 250.00, 1, 2)",
2802+
"INSERT INTO categories VALUES (1, 'Electronics', 1), (2, 'Furniture', 2)",
2803+
"INSERT INTO suppliers VALUES (1, 'TechCorp', 5), (2, 'GadgetInc', 4), (3, 'OfficeSupply', 3)",
2804+
},
2805+
Assertions: []ScriptTestAssertion{
2806+
{
2807+
Skip: true,
2808+
Query: "SELECT category_id, GROUP_CONCAT(name ORDER BY (SELECT rating FROM suppliers WHERE suppliers.id = products.supplier_id) DESC, id ASC) FROM products GROUP BY category_id ORDER BY category_id",
2809+
Expected: []sql.Row{{1, "Laptop,Keyboard,Mouse,Monitor"}, {2, "Chair,Desk"}},
2810+
},
2811+
{
2812+
Skip: true,
2813+
Query: "SELECT GROUP_CONCAT(name ORDER BY (SELECT COUNT(*) FROM products p2 WHERE p2.price < products.price), id) FROM products",
2814+
Expected: []sql.Row{{"Mouse,Keyboard,Chair,Monitor,Desk,Laptop"}},
2815+
},
2816+
{
2817+
Skip: true,
2818+
Query: "SELECT category_id, GROUP_CONCAT(DISTINCT supplier_id ORDER BY (SELECT rating FROM suppliers WHERE suppliers.id = products.supplier_id)) FROM products GROUP BY category_id",
2819+
Expected: []sql.Row{{1, "2,1"}, {2, "3"}},
2820+
},
2821+
{
2822+
Skip: true,
2823+
Query: "SELECT GROUP_CONCAT(name ORDER BY (SELECT priority FROM categories WHERE categories.id = products.category_id), price) FROM products",
2824+
Expected: []sql.Row{{"Mouse,Keyboard,Monitor,Laptop,Chair,Desk"}},
2825+
},
2826+
{
2827+
Query: "SELECT category_id, GROUP_CONCAT(name ORDER BY (SELECT AVG(price) FROM products p2 WHERE p2.category_id = products.category_id) DESC, name) FROM products GROUP BY category_id ORDER BY category_id",
2828+
Expected: []sql.Row{{1, "Keyboard,Laptop,Monitor,Mouse"}, {2, "Chair,Desk"}},
2829+
},
2830+
},
2831+
},
2832+
{
2833+
Name: "Group Concat Subquery ORDER BY Error Cases",
2834+
Dialect: "mysql",
2835+
SetUpScript: []string{
2836+
"CREATE TABLE test_table (id INT PRIMARY KEY, name VARCHAR(50), value INT)",
2837+
"INSERT INTO test_table VALUES (1, 'A', 10), (2, 'B', 20), (3, 'C', 30)",
2838+
},
2839+
Assertions: []ScriptTestAssertion{
2840+
{
2841+
Query: "SELECT GROUP_CONCAT(name ORDER BY (SELECT name, value FROM test_table t2 WHERE t2.id = test_table.id)) FROM test_table",
2842+
ExpectedErr: sql.ErrInvalidOperandColumns,
2843+
},
2844+
{
2845+
Query: "SELECT GROUP_CONCAT(name ORDER BY (SELECT value FROM test_table)) FROM test_table",
2846+
ExpectedErr: sql.ErrExpectedSingleRow,
2847+
},
2848+
},
2849+
},
2850+
{
2851+
Name: "Group Concat Subquery ORDER BY Additional Edge Cases",
2852+
Dialect: "mysql",
2853+
SetUpScript: []string{
2854+
"CREATE TABLE complex_test (id INT PRIMARY KEY, name VARCHAR(50), value INT, category VARCHAR(10), created_at DATE)",
2855+
"INSERT INTO complex_test VALUES (1, 'Alpha', 100, 'X', '2023-01-01')",
2856+
"INSERT INTO complex_test VALUES (2, 'Beta', 50, 'Y', '2023-01-15')",
2857+
"INSERT INTO complex_test VALUES (3, 'Gamma', 75, 'X', '2023-02-01')",
2858+
"INSERT INTO complex_test VALUES (4, 'Delta', 25, 'Z', '2023-02-15')",
2859+
"INSERT INTO complex_test VALUES (5, 'Epsilon', 90, 'Y', '2023-03-01')",
2860+
},
2861+
Assertions: []ScriptTestAssertion{
2862+
{
2863+
// Test with subquery returning NULL values
2864+
Skip: true,
2865+
Query: "SELECT category, GROUP_CONCAT(name ORDER BY (SELECT CASE WHEN complex_test.value > 80 THEN NULL ELSE complex_test.value END), name) FROM complex_test GROUP BY category ORDER BY category",
2866+
Expected: []sql.Row{{"X", "Alpha,Gamma"}, {"Y", "Epsilon,Beta"}, {"Z", "Delta"}},
2867+
},
2868+
{
2869+
// Test with correlated subquery using multiple tables
2870+
Skip: true,
2871+
Query: "SELECT GROUP_CONCAT(name ORDER BY (SELECT COUNT(*) FROM complex_test c2 WHERE c2.category = complex_test.category AND c2.value > complex_test.value), name) FROM complex_test",
2872+
Expected: []sql.Row{{"Alpha,Delta,Epsilon,Beta,Gamma"}},
2873+
},
2874+
{
2875+
// Test with subquery using aggregate functions with HAVING
2876+
Skip: true,
2877+
Query: "SELECT category, GROUP_CONCAT(name ORDER BY (SELECT AVG(value), name FROM complex_test c2 WHERE c2.id <= complex_test.id HAVING AVG(value) > 50) DESC) FROM complex_test GROUP BY category ORDER BY category",
2878+
Expected: []sql.Row{{"X", "Alpha,Gamma"}, {"Y", "Beta,Epsilon"}, {"Z", "Delta"}},
2879+
},
2880+
{
2881+
// Test with DISTINCT and complex subquery
2882+
Query: "SELECT GROUP_CONCAT(DISTINCT category ORDER BY (SELECT SUM(value) FROM complex_test c2 WHERE c2.category = complex_test.category) DESC SEPARATOR '|') FROM complex_test",
2883+
Expected: []sql.Row{{"X|Y|Z"}},
2884+
},
2885+
{
2886+
// Test with nested subqueries
2887+
Skip: true,
2888+
Query: "SELECT GROUP_CONCAT(name ORDER BY (SELECT COUNT(*) FROM complex_test c2 WHERE c2.value > (SELECT MIN(value) FROM complex_test c3 WHERE c3.category = complex_test.category))) FROM complex_test",
2889+
Expected: []sql.Row{{"Gamma,Alpha,Epsilon,Beta,Delta"}},
2890+
},
2891+
},
2892+
},
2893+
{
2894+
Name: "Group Concat Subquery ORDER BY Performance and Boundary Cases",
2895+
Dialect: "mysql",
2896+
SetUpScript: []string{
2897+
"CREATE TABLE perf_test (id INT PRIMARY KEY, data VARCHAR(10), weight DECIMAL(5,2))",
2898+
"INSERT INTO perf_test VALUES (1, 'A', 1.5), (2, 'B', 2.5), (3, 'C', 0.5), (4, 'D', 3.5), (5, 'E', 2.0)",
2899+
},
2900+
Assertions: []ScriptTestAssertion{
2901+
{
2902+
// Test with subquery returning same value for multiple rows (stability)
2903+
Query: "SELECT GROUP_CONCAT(data ORDER BY (SELECT 42), id) FROM perf_test",
2904+
Expected: []sql.Row{{"A,B,C,D,E"}},
2905+
},
2906+
{
2907+
// Test with subquery using LIMIT
2908+
Skip: true,
2909+
Query: "SELECT GROUP_CONCAT(data ORDER BY (SELECT weight FROM perf_test p2 WHERE p2.id = perf_test.id LIMIT 1)) FROM perf_test",
2910+
Expected: []sql.Row{{"C,A,E,B,D"}},
2911+
},
2912+
{
2913+
// Test with very small decimal differences in ORDER BY subquery
2914+
Skip: true,
2915+
Query: "SELECT GROUP_CONCAT(data ORDER BY (SELECT weight + 0.001 * perf_test.id FROM perf_test p2 WHERE p2.id = perf_test.id)) FROM perf_test",
2916+
Expected: []sql.Row{{"C,A,E,B,D"}},
2917+
},
2918+
},
2919+
},
27632920
{
27642921
Name: "CONVERT USING still converts between incompatible character sets",
27652922
Dialect: "mysql",
@@ -2998,7 +3155,7 @@ CREATE TABLE tab3 (
29983155
`CREATE TABLE t1 (pk int PRIMARY KEY, v1 varchar(10))`,
29993156
`INSERT INTO t1 VALUES (1,"1"), (2,"2"), (3,"3")`,
30003157
`CREATE TABLE t2 AS SELECT * FROM t1`,
3001-
//`CREATE TABLE t3(v0 int) AS SELECT pk FROM t1`, // parser problems
3158+
// `CREATE TABLE t3(v0 int) AS SELECT pk FROM t1`, // parser problems
30023159
`CREATE TABLE t3 AS SELECT pk FROM t1`,
30033160
`CREATE TABLE t4 AS SELECT pk, v1 FROM t1`,
30043161
`CREATE TABLE t5 SELECT * FROM t1 ORDER BY pk LIMIT 1`,
@@ -3163,7 +3320,7 @@ CREATE TABLE tab3 (
31633320
},
31643321
},
31653322
},
3166-
//todo(max): fix arithmatic on bindvar typing
3323+
// todo(max): fix arithmatic on bindvar typing
31673324
SkipPrepared: true,
31683325
},
31693326
{
@@ -4193,7 +4350,7 @@ CREATE TABLE tab3 (
41934350
// but GMS builds GroupBy for any aggregate function.
41944351
Skip: true,
41954352
Query: "select count(*) from numbers having count(*) > val;",
4196-
//ExpectedErrStr: "found HAVING clause with no GROUP BY", // not the exact error we want
4353+
// ExpectedErrStr: "found HAVING clause with no GROUP BY", // not the exact error we want
41974354
},
41984355
{
41994356
Query: "select count(*) from numbers group by val having count(*) < val;",
@@ -4205,7 +4362,7 @@ CREATE TABLE tab3 (
42054362
Name: "using having and group by clauses in subquery ",
42064363
SetUpScript: []string{
42074364
"CREATE TABLE t (i int, t varchar(2));",
4208-
"insert into t values (1, 'a'), (1, 'a2'), (2, 'b'), (3, 'c'), (3, 'c2'), (4, 'd'), (5, 'e'), (5, 'e2');", //, (6, 'f'), (7, 'g'), (7, 'g2')
4365+
"insert into t values (1, 'a'), (1, 'a2'), (2, 'b'), (3, 'c'), (3, 'c2'), (4, 'd'), (5, 'e'), (5, 'e2');", // , (6, 'f'), (7, 'g'), (7, 'g2')
42094366
},
42104367
Assertions: []ScriptTestAssertion{
42114368
{

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-20250530231040-bfd522856394
9+
github.com/dolthub/vitess v0.0.0-20250604183723-cad71bbe21d0
1010
github.com/go-kit/kit v0.10.0
1111
github.com/go-sql-driver/mysql v1.7.2-0.20231213112541-0004702b931d
1212
github.com/gocraft/dbr/v2 v2.7.2

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9X
6060
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81/go.mod h1:siLfyv2c92W1eN/R4QqG/+RjjX5W2+gCTRjZxBjI3TY=
6161
github.com/dolthub/vitess v0.0.0-20250530231040-bfd522856394 h1:sMwntvk7O9dttaJLqnOvy8zgk0ah9qnyWkAahfOgnIo=
6262
github.com/dolthub/vitess v0.0.0-20250530231040-bfd522856394/go.mod h1:1gQZs/byeHLMSul3Lvl3MzioMtOW1je79QYGyi2fd70=
63+
github.com/dolthub/vitess v0.0.0-20250604183723-cad71bbe21d0 h1:esaEESlRNds2thjx9mEiDRIp1Cm5nM9K2PbYqPKei5Q=
64+
github.com/dolthub/vitess v0.0.0-20250604183723-cad71bbe21d0/go.mod h1:1gQZs/byeHLMSul3Lvl3MzioMtOW1je79QYGyi2fd70=
6365
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
6466
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
6567
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=

server/handler.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,21 +453,21 @@ func (h *Handler) doQuery(
453453
if queryStr != "" {
454454
sqlCtx.SetLogger(sqlCtx.GetLogger().WithField("query", queryStr))
455455
}
456-
sqlCtx.GetLogger().Debugf("Starting query")
456+
sqlCtx.GetLogger().WithField(sql.QueryTimeLogKey, time.Now()).Debugf("Starting query")
457457

458458
finish := observeQuery(sqlCtx, query)
459459
defer func() {
460460
finish(err)
461461
}()
462462

463-
sqlCtx.GetLogger().Tracef("beginning execution")
463+
sqlCtx.GetLogger().WithField(sql.QueryTimeLogKey, time.Now()).Tracef("beginning execution")
464464

465465
var schema sql.Schema
466466
var rowIter sql.RowIter
467467
qFlags.Set(sql.QFlagDeferProjections)
468468
schema, rowIter, qFlags, err = queryExec(sqlCtx, query, parsed, analyzedPlan, bindings, qFlags)
469469
if err != nil {
470-
sqlCtx.GetLogger().WithError(err).Warn("error running query")
470+
sqlCtx.GetLogger().WithField(sql.QueryTimeLogKey, time.Now()).WithError(err).Warn("error running query")
471471
if verboseErrorLogging {
472472
fmt.Printf("Err: %+v", err)
473473
}
@@ -514,7 +514,7 @@ func (h *Handler) doQuery(
514514
sqlCtx.GetLogger().Tracef("returning result %v", r)
515515
}
516516

517-
sqlCtx.GetLogger().Debugf("Query finished in %d ms", time.Since(start).Milliseconds())
517+
sqlCtx.GetLogger().WithField(sql.QueryTimeLogKey, time.Now()).Debugf("Query finished in %d ms", time.Since(start).Milliseconds())
518518

519519
// processedAtLeastOneBatch means we already called callback() at least
520520
// once, so no need to call it if RowsAffected == 0.

server/handler_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/dolthub/vitess/go/race"
3030
"github.com/dolthub/vitess/go/sqltypes"
3131
"github.com/dolthub/vitess/go/vt/proto/query"
32+
"github.com/sirupsen/logrus"
3233
"github.com/stretchr/testify/assert"
3334
"github.com/stretchr/testify/require"
3435

@@ -1916,3 +1917,79 @@ func TestStatusVariableComUpdate(t *testing.T) {
19161917
checkSessionStatVar(t, sess1, "Com_update", uint64(5))
19171918
checkSessionStatVar(t, sess2, "Com_update", uint64(3))
19181919
}
1920+
1921+
// TestLoggerFieldsSetup tests that handler properly sets up logger fields including query time
1922+
func TestLoggerFieldsSetup(t *testing.T) {
1923+
e, pro := setupMemDB(require.New(t))
1924+
dbFunc := pro.Database
1925+
1926+
handler := &Handler{
1927+
e: e,
1928+
sm: NewSessionManager(
1929+
sql.NewContext,
1930+
testSessionBuilder(pro),
1931+
sql.NoopTracer,
1932+
dbFunc,
1933+
sql.NewMemoryManager(nil),
1934+
sqle.NewProcessList(),
1935+
"foo",
1936+
),
1937+
readTimeout: time.Second,
1938+
}
1939+
1940+
conn := newConn(1)
1941+
handler.NewConnection(conn)
1942+
err := handler.ComInitDB(conn, "test")
1943+
require.NoError(t, err)
1944+
1945+
// Execute a query and verify basic logging setup
1946+
err = handler.ComQuery(context.Background(), conn, "SELECT 1", dummyCb)
1947+
require.NoError(t, err)
1948+
1949+
// Verify that the session's logger has the expected fields
1950+
session := handler.sm.session(conn)
1951+
logger := session.GetLogger()
1952+
require.NotNil(t, logger, "Session should have a logger")
1953+
1954+
// Verify that the logger has the expected fields
1955+
require.Contains(t, logger.Data, sql.ConnectTimeLogKey, "Logger should contain connect time")
1956+
require.Contains(t, logger.Data, sql.ConnectionIdLogField, "Logger should contain connection ID")
1957+
1958+
// Verify that queryTime is actually used in logs by capturing a log entry
1959+
var capturedFields logrus.Fields
1960+
hook := &testHook{fields: &capturedFields}
1961+
logrus.AddHook(hook)
1962+
defer logrus.StandardLogger().ReplaceHooks(make(logrus.LevelHooks))
1963+
1964+
// Execute a query that will trigger error logging (which includes queryTime)
1965+
err = handler.ComQuery(context.Background(), conn, "SELECT * FROM nonexistent_table", dummyCb)
1966+
require.Error(t, err) // This should cause an error log with queryTime
1967+
1968+
// Verify that the log entry contained queryTime
1969+
require.Contains(t, capturedFields, sql.QueryTimeLogKey, "Log entry should contain queryTime field")
1970+
1971+
// Verify the values are of correct types
1972+
connectTime, ok := logger.Data[sql.ConnectTimeLogKey].(time.Time)
1973+
require.True(t, ok, "Connect time should be a time.Time")
1974+
require.False(t, connectTime.IsZero(), "Connect time should not be zero")
1975+
1976+
connID, ok := logger.Data[sql.ConnectionIdLogField].(uint32)
1977+
require.True(t, ok, "Connection ID should be a uint32")
1978+
require.Equal(t, conn.ConnectionID, connID, "Connection ID should match")
1979+
}
1980+
1981+
// Simple hook to capture log fields for testing
1982+
type testHook struct {
1983+
fields *logrus.Fields
1984+
}
1985+
1986+
func (h *testHook) Levels() []logrus.Level {
1987+
return []logrus.Level{logrus.WarnLevel} // Only capture warning level (error logs)
1988+
}
1989+
1990+
func (h *testHook) Fire(entry *logrus.Entry) error {
1991+
if entry.Message == "error running query" {
1992+
*h.fields = entry.Data
1993+
}
1994+
return nil
1995+
}

sql/expression/isnull.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ func (e *IsNull) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
5454
return nil, err
5555
}
5656

57+
// Slices of typed values (e.g. Record and Composite types in Postgres) evaluate
58+
// to NULL if all of their entries are NULL.
59+
if tupleValue, ok := v.([]types.TupleValue); ok {
60+
for _, typedValue := range tupleValue {
61+
if typedValue.Value != nil {
62+
return false, nil
63+
}
64+
}
65+
return true, nil
66+
}
67+
5768
return v == nil, nil
5869
}
5970

sql/log.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ const (
1818
ConnectionIdLogField = "connectionID"
1919
ConnectionDbLogField = "connectionDb"
2020
ConnectTimeLogKey = "connectTime"
21+
QueryTimeLogKey = "queryTime"
2122
)

sql/types/tuple_value.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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 types
16+
17+
import "github.com/dolthub/go-mysql-server/sql"
18+
19+
// TupleValue represents a value and its associated type information. TupleValue is used by collections of
20+
// values where the type information is not consistent across all values (e.g. Records in Postgres).
21+
type TupleValue struct {
22+
Value any
23+
Type sql.Type
24+
}

0 commit comments

Comments
 (0)