Skip to content

Commit 70a3a2b

Browse files
author
James Cor
committed
Merge branch 'main' into james/proc
2 parents e64f37f + ea55201 commit 70a3a2b

File tree

9 files changed

+75
-10
lines changed

9 files changed

+75
-10
lines changed

enginetest/queries/json_scripts.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ var JsonScripts = []ScriptTest{
627627
SetUpScript: []string{
628628
"create table t (pk int primary key, col1 JSON, col2 JSON);",
629629
`insert into t values (1, JSON_OBJECT('key1', 1, 'key2', '"abc"'), JSON_ARRAY(3,10,5,17,"z"));`,
630-
`insert into t values (2, JSON_OBJECT('key1', 100, 'key2', '"ghi"'), JSON_ARRAY(3,10,5,17,JSON_ARRAY(22,"y",66)));`,
630+
`insert into t values (2, JSON_OBJECT('key1', 100, 'key2', 'ghi'), JSON_ARRAY(3,10,5,17,JSON_ARRAY(22,"y",66)));`,
631631
`CREATE TABLE t2 (i INT PRIMARY KEY, j JSON);`,
632632
`INSERT INTO t2 VALUES (0, '{"a": "123", "outer": {"inner": 456}}');`,
633633
},
@@ -636,16 +636,23 @@ var JsonScripts = []ScriptTest{
636636
Query: `select col1->'$.key1' from t;`,
637637
Expected: []sql.Row{{types.MustJSON("1")}, {types.MustJSON("100")}},
638638
},
639+
{
640+
Query: `select col1->'$.key2' from t;`,
641+
Expected: []sql.Row{
642+
{types.JSONDocument{Val: "\"abc\""}},
643+
{types.JSONDocument{Val: "ghi"}},
644+
},
645+
},
639646
{
640647
Query: `select col1->>'$.key2' from t;`,
641-
Expected: []sql.Row{{"abc"}, {"ghi"}},
648+
Expected: []sql.Row{{"\"abc\""}, {"ghi"}},
642649
},
643650
{
644651
Query: `select pk, col1 from t where col1->'$.key1' = 1;`,
645652
Expected: []sql.Row{{1, types.MustJSON(`{"key1":1, "key2":"\"abc\""}`)}},
646653
},
647654
{
648-
Query: `select pk, col1 from t where col1->>'$.key2' = 'abc';`,
655+
Query: `select pk, col1 from t where col1->>'$.key2' = '"abc"';`,
649656
Expected: []sql.Row{{1, types.MustJSON(`{"key1":1, "key2":"\"abc\""}`)}},
650657
},
651658
{

enginetest/queries/queries.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5412,6 +5412,12 @@ SELECT * FROM cte WHERE d = 2;`,
54125412
},
54135413
},
54145414
},
5415+
{
5416+
Query: `SELECT COALESCE(CAST('{"a": "one \\n two"}' as json), '');`,
5417+
Expected: []sql.Row{
5418+
{"{\"a\": \"one \\n two\"}"},
5419+
},
5420+
},
54155421
{
54165422
Query: "SELECT concat(s, i) FROM mytable",
54175423
Expected: []sql.Row{
@@ -9854,6 +9860,18 @@ from typestable`,
98549860
{"NULL"},
98559861
},
98569862
},
9863+
{
9864+
Query: `SELECT json_type(json_extract('{"a": 123}', null));`,
9865+
Expected: []sql.Row{
9866+
{"NULL"},
9867+
},
9868+
},
9869+
{
9870+
Query: `SELECT json_type(json_extract('{"a": 123}', '$.a', null));`,
9871+
Expected: []sql.Row{
9872+
{"NULL"},
9873+
},
9874+
},
98579875
{
98589876
Query: "SELECT json_type(cast(cast('2001-01-01 12:34:56.123456' as datetime) as json));",
98599877
Expected: []sql.Row{

processlist.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ func (pl *ProcessList) BeginQuery(
113113
ctx *sql.Context,
114114
query string,
115115
) (*sql.Context, error) {
116+
if ctx.IsInterpreted() {
117+
return ctx, nil
118+
}
116119
pl.mu.Lock()
117120
defer pl.mu.Unlock()
118121

@@ -144,6 +147,9 @@ func (pl *ProcessList) BeginQuery(
144147
}
145148

146149
func (pl *ProcessList) EndQuery(ctx *sql.Context) {
150+
if ctx.IsInterpreted() {
151+
return
152+
}
147153
pl.mu.Lock()
148154
defer pl.mu.Unlock()
149155
id := ctx.Session.ID()
@@ -177,6 +183,9 @@ func (pl *ProcessList) EndQuery(ctx *sql.Context) {
177183
// bracketed with EndOperation(). Should certainly be used for any
178184
// Handler callbacks which may access the database, like Prepare.
179185
func (pl *ProcessList) BeginOperation(ctx *sql.Context) (*sql.Context, error) {
186+
if ctx.IsInterpreted() {
187+
return ctx, nil
188+
}
180189
pl.mu.Lock()
181190
defer pl.mu.Unlock()
182191
id := ctx.Session.ID()
@@ -193,6 +202,9 @@ func (pl *ProcessList) BeginOperation(ctx *sql.Context) (*sql.Context, error) {
193202
}
194203

195204
func (pl *ProcessList) EndOperation(ctx *sql.Context) {
205+
if ctx.IsInterpreted() {
206+
return
207+
}
196208
pl.mu.Lock()
197209
defer pl.mu.Unlock()
198210
id := ctx.Session.ID()

sql/expression/function/coalesce_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ func TestCoalesce(t *testing.T) {
152152
typ: types.Float64,
153153
nullable: false,
154154
},
155+
{
156+
name: "coalesce(json({'a': 'a \n b'}), '')",
157+
input: []sql.Expression{
158+
expression.NewLiteral("{\"a\": \"one \\n two\"}", types.JSON),
159+
expression.NewLiteral("", types.LongText),
160+
},
161+
expected: "{\"a\": \"one \\n two\"}",
162+
typ: types.LongText,
163+
nullable: false,
164+
},
155165
{
156166
name: "coalesce(sysInt, sysInt)",
157167
input: []sql.Expression{

sql/expression/function/json/json_extract.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ func (j *JSONExtract) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
102102
return nil, err
103103
}
104104

105+
if path == nil {
106+
return nil, nil
107+
}
108+
105109
results[i], err = types.LookupJSONValue(searchable, path.(string))
106110
if err != nil {
107111
return nil, fmt.Errorf("failed to extract from expression '%s'; %s", j.JSON.String(), err.Error())

sql/rowexec/transaction_iters.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type TransactionCommittingIter struct {
7878

7979
func AddTransactionCommittingIter(ctx *sql.Context, qFlags *sql.QueryFlags, iter sql.RowIter) (sql.RowIter, error) {
8080
// TODO: This is a bit of a hack. Need to figure out better relationship between new transaction node and warnings.
81-
if qFlags != nil && qFlags.IsSet(sql.QFlagShowWarnings) {
81+
if (qFlags != nil && qFlags.IsSet(sql.QFlagShowWarnings)) || ctx.IsInterpreted() {
8282
return iter, nil
8383
}
8484

sql/session.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ type Context struct {
262262
queryTime time.Time
263263
tracer trace.Tracer
264264
rootSpan trace.Span
265+
interpreted bool
265266
Version AnalyzerVersion
266267
}
267268

@@ -335,6 +336,17 @@ func RunWithNowFunc(nowFunc func() time.Time, fn func() error) error {
335336
return fn()
336337
}
337338

339+
// RunInterpreted modifies the context such that all calls to Context.IsInterpreted will return `true`. It is safe to
340+
// recursively call this.
341+
func RunInterpreted[T any](ctx *Context, f func(ctx *Context) (T, error)) (T, error) {
342+
current := ctx.interpreted
343+
ctx.interpreted = true
344+
defer func() {
345+
ctx.interpreted = current
346+
}()
347+
return f(ctx)
348+
}
349+
338350
func swapNowFunc(newNowFunc func() time.Time) func() time.Time {
339351
ctxNowFuncMutex.Lock()
340352
defer ctxNowFuncMutex.Unlock()
@@ -395,6 +407,13 @@ func (c *Context) ApplyOpts(opts ...ContextOption) {
395407
// NewEmptyContext returns a default context with default values.
396408
func NewEmptyContext() *Context { return NewContext(context.TODO()) }
397409

410+
// IsInterpreted returns `true` when this is being called from within RunInterpreted. In such cases, GMS will choose to
411+
// handle logic differently, as running from within an interpreted function requires different considerations than
412+
// running in a standard environment.
413+
func (c *Context) IsInterpreted() bool {
414+
return c.interpreted
415+
}
416+
398417
// Pid returns the process id associated with this context.
399418
func (c *Context) Pid() uint64 {
400419
if c == nil {

sql/types/json_value.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func JsonToMySqlString(jsonWrapper sql.JSONWrapper) (string, error) {
4343
return marshalToMySqlString(val)
4444
}
4545

46-
// JsonToMySqlString generates a byte slice representation of a sql.JSONWrapper that is compatible with MySQL's JSON output, including spaces.
46+
// JsonToMySqlBytes generates a byte slice representation of a sql.JSONWrapper that is compatible with MySQL's JSON output, including spaces.
4747
func JsonToMySqlBytes(jsonWrapper sql.JSONWrapper) ([]byte, error) {
4848
val, err := jsonWrapper.ToInterface()
4949
if err != nil {

sql/types/strings.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"github.com/shopspring/decimal"
3030
"gopkg.in/src-d/go-errors.v1"
3131

32-
"github.com/dolthub/go-mysql-server/internal/strings"
3332
"github.com/dolthub/go-mysql-server/sql"
3433
"github.com/dolthub/go-mysql-server/sql/encodings"
3534
)
@@ -416,10 +415,6 @@ func ConvertToBytes(ctx context.Context, v interface{}, t sql.StringType, dest [
416415
if err != nil {
417416
return nil, err
418417
}
419-
val, err = strings.UnquoteBytes(val)
420-
if err != nil {
421-
return nil, err
422-
}
423418
start = 0
424419
case sql.Wrapper[string]:
425420
unwrapped, err := s.Unwrap(ctx)

0 commit comments

Comments
 (0)