Skip to content

Commit

Permalink
expression: do not set ParseToJSONFlag to a JSON column (#8564) (#8660)
Browse files Browse the repository at this point in the history
  • Loading branch information
XuHuaiyu authored and ngaut committed Dec 12, 2018
1 parent 9ab1a50 commit 47fe9e1
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
2 changes: 1 addition & 1 deletion expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,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
13 changes: 6 additions & 7 deletions expression/builtin_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package expression
import (
"github.com/pingcap/errors"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/types/json"
Expand Down Expand Up @@ -171,7 +170,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 @@ -215,7 +214,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 @@ -255,7 +254,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 @@ -295,7 +294,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 @@ -431,7 +430,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 @@ -494,7 +493,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 @@ -503,3 +503,15 @@ func ColumnSliceIsIntersect(s1, s2 []*Column) bool {
}
return false
}

// 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 47fe9e1

Please sign in to comment.