Skip to content

Commit

Permalink
expression: do not set ParseToJSONFlag to a JSON column (pingcap#8564)
Browse files Browse the repository at this point in the history
  • Loading branch information
XuHuaiyu committed Dec 12, 2018
1 parent fe00792 commit 475ff42
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
2 changes: 1 addition & 1 deletion expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@ func (c *compareFunctionClass) generateCmpSigs(ctx sessionctx.Context, args []Ex
if tp == types.ETJson {
// In compare, if we cast string to JSON, we shouldn't parse it.
for i := range args {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
}
bf.tp.Flen = 1
Expand Down
15 changes: 7 additions & 8 deletions expression/builtin_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
package expression

import (
"github.com/juju/errors"
"github.com/pingcap/errors"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/types/json"
Expand Down Expand Up @@ -180,7 +179,7 @@ func (c *jsonUnquoteFunctionClass) getFunction(ctx sessionctx.Context, args []Ex
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETJson)
args[0].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[0])
sig := &builtinJSONUnquoteSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonUnquoteSig)
return sig, nil
Expand Down Expand Up @@ -224,7 +223,7 @@ func (c *jsonSetFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 2; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONSetSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonSetSig)
Expand Down Expand Up @@ -264,7 +263,7 @@ func (c *jsonInsertFunctionClass) getFunction(ctx sessionctx.Context, args []Exp
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 2; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONInsertSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonInsertSig)
Expand Down Expand Up @@ -304,7 +303,7 @@ func (c *jsonReplaceFunctionClass) getFunction(ctx sessionctx.Context, args []Ex
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 2; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONReplaceSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonReplaceSig)
Expand Down Expand Up @@ -440,7 +439,7 @@ func (c *jsonObjectFunctionClass) getFunction(ctx sessionctx.Context, args []Exp
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 1; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONObjectSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonObjectSig)
Expand Down Expand Up @@ -503,7 +502,7 @@ func (c *jsonArrayFunctionClass) getFunction(ctx sessionctx.Context, args []Expr
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := range args {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONArraySig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonArraySig)
Expand Down
12 changes: 12 additions & 0 deletions expression/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,15 @@ func extractFiltersFromDNF(ctx sessionctx.Context, dnfFunc *ScalarFunction) ([]E
}
return extractedExpr, ComposeDNFCondition(ctx, newDNFItems...)
}

// DisableParseJSONFlag4Expr disables ParseToJSONFlag for `expr` except Column.
// We should not *PARSE* a string as JSON under some scenarios. ParseToJSONFlag
// is 0 for JSON column yet, so we can skip it. Moreover, Column.RetType refers
// to the infoschema, if we modify it, data race may happen if another goroutine
// read from the infoschema at the same time.
func DisableParseJSONFlag4Expr(expr Expression) {
if _, isColumn := expr.(*Column); isColumn {
return
}
expr.GetType().Flag &= ^mysql.ParseToJSONFlag
}

0 comments on commit 475ff42

Please sign in to comment.