Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expression:add support for JSON_MERGE_PRESERVE #8931

Merged
merged 6 commits into from Jan 11, 2019
Merged
Changes from 4 commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -403,6 +403,11 @@ func (b *builtinJSONMergeSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNu
values = append(values, value)
}
res = json.MergeBinary(values)
// function "JSON_MERGE" is deprecated since MySQL 5.7.22. Synonym for function "JSON_MERGE_PRESERVE".
// See https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-merge
if b.pbCode == tipb.ScalarFuncSig_JsonMergeSig {
b.ctx.GetSessionVars().StmtCtx.AppendWarning(errDeprecatedSyntaxNoReplacement.GenWithStackByArgs("JSON_MERGE"))
}
return res, false, nil
}

@@ -720,7 +725,17 @@ type jsonMergePreserveFunctionClass struct {
}

func (c *jsonMergePreserveFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "JSON_MERGE_PRESERVE")
if err := c.verifyArgs(args); err != nil {
return nil, err
}
argTps := make([]types.EvalType, 0, len(args))
for range args {
argTps = append(argTps, types.ETJson)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
This conversation was marked as resolved by zz-jason

This comment has been minimized.

Copy link
@zz-jason

zz-jason Jan 8, 2019

Member

I think we don't need to support another function signature, since they share the same code logic. How about return builtinJSONMergeSig{} in this function?

This comment has been minimized.

Copy link
@shinytang6

shinytang6 Jan 8, 2019

Author Contributor

Thanks, PTAL. And I think the implementation of signature should be placed in builtinJSONMergePreserveSig, since JSON_Merge is deprecated. Do you think it necessary?

This comment has been minimized.

Copy link
@zz-jason

zz-jason Jan 9, 2019

Member

I think we can remain the current code, let the implementation of signature be placed in builtinJSONMergeSig.

sig := &builtinJSONMergeSig{bf}
This conversation was marked as resolved by lamxTyler

This comment has been minimized.

Copy link
@lamxTyler

This comment has been minimized.

Copy link
@shinytang6

shinytang6 Jan 9, 2019

Author Contributor

It seems so. So what do you suggest I should do? Removing the warning? Cause I see there are still some deprecated expressions without any warnings in the codebase.

This comment has been minimized.

Copy link
@lamxTyler

lamxTyler Jan 9, 2019

Member

What about adding a field to indicate if it is built from json_merge_preserve or just check it's pb_code to differentiate them?

This comment has been minimized.

Copy link
@shinytang6

shinytang6 Jan 9, 2019

Author Contributor

ok, PTAL

sig.setPbCode(tipb.ScalarFuncSig_JsonMergePreserveSig)
return sig, nil
}

type jsonPrettyFunctionClass struct {
@@ -187,6 +187,39 @@ func (s *testEvaluatorSuite) TestJSONMerge(c *C) {
j2 := d.GetMysqlJSON()
cmp := json.CompareBinary(j1, j2)
c.Assert(cmp, Equals, 0, Commentf("got %v expect %v", j1.String(), j2.String()))
case nil:
c.Assert(d.IsNull(), IsTrue)
}
}
}

func (s *testEvaluatorSuite) TestJSONMergePreserve(c *C) {
defer testleak.AfterTest(c)()
fc := funcs[ast.JSONMergePreserve]
tbl := []struct {
Input []interface{}
Expected interface{}
}{
{[]interface{}{nil, nil}, nil},
{[]interface{}{`{}`, `[]`}, `[{}]`},
{[]interface{}{`{}`, `[]`, `3`, `"4"`}, `[{}, 3, "4"]`},
}
for _, t := range tbl {
args := types.MakeDatums(t.Input...)
f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
c.Assert(err, IsNil)
d, err := evalBuiltinFunc(f, chunk.Row{})
c.Assert(err, IsNil)

switch x := t.Expected.(type) {
case string:
j1, err := json.ParseBinaryFromString(x)
c.Assert(err, IsNil)
j2 := d.GetMysqlJSON()
cmp := json.CompareBinary(j1, j2)
c.Assert(cmp, Equals, 0, Commentf("got %v expect %v", j1.String(), j2.String()))
case nil:
c.Assert(d.IsNull(), IsTrue)
}
This conversation was marked as resolved by qw4990

This comment has been minimized.

Copy link
@qw4990

qw4990 Jan 11, 2019

Contributor

case nil: should be checked?
In this case, d.IsNull() should be true.

This comment has been minimized.

Copy link
@shinytang6

shinytang6 Jan 11, 2019

Author Contributor

PTAL

}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.